Python高度関数要約(二)

2748 ワード

filter
Pythonに組み込まれたfilter()関数は、シーケンスをフィルタするために使用されます.map()と同様に、filter()も関数とシーケンスを受信する.map()と異なる場合、filter()は、入力された関数を各要素に順次作用させ、戻り値がTrueであるかFalseであるかに基づいて、その要素を保持するか廃棄するかを決定する.
たとえば、listで偶数を削除し、奇数だけを残します.
def is_odd(n):
    return n % 2 == 1

filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
#   : [1, 5, 9, 15]

1つのシーケンスの空の文字列を削除するには、次のように書くことができます.
def not_empty(s):
    return s and s.strip()

filter(not_empty, ['A', '', 'B', None, 'C', '  '])
#   : ['A', 'B', 'C']
filter()という高次関数を用いることがわかり、重要なのは「フィルタ」関数を正しく実現することである.
sorted
ソートアルゴリズム
ソートもプログラムでよく使われるアルゴリズムです.バブルソートを使用しても高速ソートを使用しても、ソートのコアは2つの要素のサイズを比較することです.数字なら直接比較できますが、文字列か2つのdictなら?数学の大きさを直接比較するのは意味がないので,比較の過程は関数によって抽象化しなければならない.通常、2つの要素xyについて、x < yと判断した場合は-1を返し、x == yと判断した場合は0を返し、x > yと判断した場合は1を返し、これにより、ソートアルゴリズムは具体的な比較過程に関心を持たず、比較結果に基づいて直接ソートすることが規定されている.
Pythonに内蔵されているsorted()関数はlistをソートできます.
>>> sorted([36, 5, 12, 9, 21])
[5, 9, 12, 21, 36]

さらに、sorted()関数も高次関数であり、カスタムソートを実現するために比較関数を受信することもできる.たとえば、逆順序でソートする場合は、reversed_cmp関数をカスタマイズできます.
def reversed_cmp(x, y):
    if x > y:
        return -1
    if x < y:
        return 1
    return 0

カスタム比較関数reversed_cmpを入力すると、逆順序ソートが可能になります.
>>> sorted([36, 5, 12, 9, 21], reversed_cmp)
[36, 21, 12, 9, 5]

文字列のソートの例を見てみましょう.
>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']

デフォルトでは、文字列のソートは、ASCIIのサイズで比較されます.'Z' < 'a'の結果、大文字Zは小文字aの前に表示されます.
次に、ソートは大文字と小文字を無視し、アルファベット順にソートすることを提案します.このアルゴリズムを実装するには、既存のコードを大きく変更する必要はありません.大文字と小文字を無視する比較アルゴリズムを定義できれば、次のことができます.
def cmp_ignore_case(s1, s2):
    u1 = s1.upper()
    u2 = s2.upper()
    if u1 < u2:
        return -1
    if u1 > u2:
        return 1
    return 0

大文字と小文字を無視して2つの文字列を比較するのは、実際には文字列を大文字(または小文字)にしてから比較します.
これにより、sortedに上記の比較関数を入力すると、大文字と小文字を無視したソートが実現されます.
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)
['about', 'bob', 'Credit', 'Zoo']

上記の例から,高次関数の抽象能力は非常に強く,コアコードは非常に簡潔に保つことができることが分かる.