Pythonのシーケンスタイプ(二)

5345 ワード

list.sortメソッドと内蔵sorted関数
  • list.sort
    listは、元のリストをコピーして新しいリストを生成することなく、リストをその場でソートするソート方法list.sortを定義する.これもその戻り値がNoneの理由で、この方法ではリストが新規に作成されないことを示しています.
    Pythonスタイル:オブジェクトをその場で変更する関数またはメソッドで、その戻り値はNoneであり、呼び出し元に入力パラメータが変化したことを知らせる.
    python 3から4 list.sortメソッドの削除を開始しました.sortedを使用して新しいシーケンスを作成するしかありません.

  • 内蔵sorted関数:
    使用法:sorted(iterable)list.sortとは異なり、元のオブジェクトをコピーし、コピーをソートし、ソート後のコピー内容を返します.list.sortsortedの関数は、reverseとkeyの2つのキーワードパラメータを受け入れることができます.
    reverse:デフォルト値はFalse、すなわち昇順、Trueの場合は降順
    key:読み込まれたのはfuncで、このfuncがオブジェクト要素に作用した値をソートの根拠としてソートしますが、オブジェクト要素は変更されません.
    >>> l = ['a', 'C', 'm', 'd', 'B']
    >>> l.sort(key=lambda x: x.lower(), reverse=True)
    >>> l
    ['m', 'd', 'C', 'B', 'a']
    
  • list.sortsortedの背後にあるソートアルゴリズムはTimsortで、彼は安定していて、何が安定しているのか、次の例を見てください.
    >>> fruits=['grape', 'raspberry', 'apple', 'banana']
    >>> sorted(fruits, key=len)
    ['grape', 'apple', 'banana', 'raspberry']
    >>> sorted(fruits, key=len, reverse=True)
    ['raspberry', 'banana', 'grape', 'apple']
    

    ソート方法は逆に、順を追って逆になると、なぜ結果が完全に逆にならないのか、これはソートが安定していることであり、2つの要素が大きさに比べられない場合、彼らの相対位置は固定され、元のリストと同じである.bisect
    bisectモジュールには2つの主要関数bisectとinsortがあり、両方とも二分ルックアップアルゴリズムを用いて秩序シーケンスで要素をルックアップし、挿入します.bisect(haystack, needle)関数は、needleをこの位置に挿入した後、haystackは昇順を維持することができ、つまり、この関数が返す位置の前の値は、needleの値以下であり、haystackは秩序を保たなければならないという条件を満たす.
    まずbisect(haystack,needle)で位置indexを検索し、その後haystackを使用することができる.insert(index,needle)は新しい値を挿入します.insortも使えます
    def ch2_17():
        """
         haystack      needle     
        """
    
        haystack = [1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30]
        needles = [0, 1, 2, 5, 8, 10, 22, 23, 29, 30, 31]
    
        row_fom = '{0:2d} @ {1:2d}     {2}{0:<2d}'
    
        def demo(bisect_fn):
            for needle in reversed(needles):
                position = bisect_fn(haystack, needle)
                offset ='  |' * position
                print(row_fom.format(needle, position, offset))
    
        if sys.argv[-1] == 'left':
            bisect_fn = bisect.bisect_left
        else:
            bisect_fn = bisect.bisect
        print('DEMO: ', bisect_fn.__name__)
        print('haystack -> ', ' '.join('%2d' % n for n in haystack))
        demo(bisect_fn)
    
    DEMO:  bisect
    haystack ->   1  4  5  6  8 12 15 20 21 23 23 26 29 30
    31 @ 14       |  |  |  |  |  |  |  |  |  |  |  |  |  |31
    30 @ 14       |  |  |  |  |  |  |  |  |  |  |  |  |  |30
    29 @ 13       |  |  |  |  |  |  |  |  |  |  |  |  |29
    23 @ 11       |  |  |  |  |  |  |  |  |  |  |23
    22 @  9       |  |  |  |  |  |  |  |  |22
    10 @  5       |  |  |  |  |10
     8 @  5       |  |  |  |  |8 
     5 @  3       |  |  |5 
     2 @  1       |2 
     1 @  1       |1 
     0 @  0     0 
    

    bisectを使用してインデックスを作成することもできます.たとえば、スコアと等級を対応させることもできます.
    def grade(score, scores = [60, 70, 80, 90], ranks = 'FDCBA'):
        i = bisect.bisect(scores, score)
        return ranks[i]
    
    l = [random.randint(50, 100) for x in range(10)]
    print(l)
    print(list(map(grade, l)))
    
    [91, 55, 87, 66, 55, 86, 93, 61, 100, 68]
    ['A', 'F', 'B', 'D', 'F', 'B', 'A', 'D', 'A', 'D']
    

    はいれつ
    リストは柔軟で簡単ですが、場合によっては100万個のランダム浮動小数点数を格納する場合、配列の背後には浮動floatオブジェクトではなく、数字の機械翻訳、すなわちバイト表現が格納されているため、最適な選択ではありません.
    配列はリストのすべての可変シーケンスに関連する操作をサポートします:pop、extend、insert、ファイルtofileの格納とファイルからfromfileの読み出しもサポートします
    from array import array
    from random import random
    
    floats = array('d', [random() for x in range(10**7)])
    with open('floats.bin', 'wb') as fp:
        floats.tofile(fp)
    
    floats2 = array('d')
    with open('floats.bin', 'rb') as fp:
        floats2.fromfile(fp)
    

    メモリビュー
    numpy
    deque
    テーブルに対してpop(index)を使用して前の要素を削除すると、削除された要素の後ろのすべての要素が移動するため、時間がかかります.
    この場合、deque双方向キューを使用することができ、これは、
  • スレッドセキュリティ
  • は、要素
  • を両端からすばやく追加または削除することができる.
  • dequeオブジェクトを作成するときにオブジェクトの長さを指定することで、キューが満員になったときに先頭に要素を追加すると、期限切れの部分
  • が削除されます.
    >>> from collections import deque
    >>> dq = deque(range(10), maxlen = 10)
    >>> dq
    deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
    >>> dq.rotate(3)
    >>> dq
    deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10)
    >>> dq.rotate(-4)
    >>> dq
    deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], maxlen=10)
    >>> dq.extend([10, 20, 30, 40])
    >>> dq
    deque([5, 6, 7, 8, 9, 0, 10, 20, 30, 40], maxlen=10)
    >>> dq.extendleft([50, 60])
    >>> dq
    deque([60, 50, 5, 6, 7, 8, 9, 0, 10, 20], maxlen=10)
    

    以上のようにdequeはrotate(steps)メソッドをサポートし、steps>0の場合、シーケンス内のすべての要素がstepsビットを右に移動し、右端のsteps個の要素がシーケンスの左側に表示され、steps<0の場合は逆になります.
    次の図はlistとdequeの方法の比較です.
    [画像のアップロードに失敗しました...(image-cab 70 f-15441191699167)]