8.3. コレクション—コンテナデータ型—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.6/library/collections
移動先:案内検索

8.3。 コレクション —コンテナのデータ型

ソースコード: :source: `Lib / collections / __ init __。py`



このモジュールは、Pythonの汎用組み込みコンテナー dictlistset 、および tuple の代替を提供する特殊なコンテナーデータ型を実装します。

namedtuple() 名前付きフィールドを持つタプルサブクラスを作成するためのファクトリ関数
deque 両端に高速な追加とポップを備えたリストのようなコンテナ
ChainMap 複数のマッピングの単一のビューを作成するためのdictのようなクラス
Counter ハッシュ可能なオブジェクトをカウントするためのdictサブクラス
OrderedDict 注文エントリが追加されたことを記憶するdictサブクラス
defaultdict 欠落値を提供するためにファクトリ関数を呼び出すdictサブクラス
UserDict dictサブクラス化を容易にするための辞書オブジェクトのラッパー
UserList リストのサブクラス化を容易にするためのリストオブジェクトのラッパー
UserString 文字列のサブクラス化を容易にするための文字列オブジェクトのラッパー

バージョン3.3で変更: コレクション抽象基本クラスcollections.abc モジュールに移動しました。 下位互換性のために、これらはこのモジュールでも引き続き表示されます。


8.3.1。 チェーンマップオブジェクト

バージョン3.3の新機能。


ChainMap クラスは、多数のマッピングをすばやくリンクして、単一のユニットとして扱うことができるようにするために提供されています。 多くの場合、新しい辞書を作成して複数の update()呼び出しを実行するよりもはるかに高速です。

このクラスは、ネストされたスコープをシミュレートするために使用でき、テンプレート作成に役立ちます。

class collections.ChainMap(*maps)

ChainMap は、複数のdictまたは他のマッピングをグループ化して、単一の更新可能なビューを作成します。 maps が指定されていない場合は、空のディクショナリが1つ提供されるため、新しいチェーンには常に少なくとも1つのマッピングがあります。

基になるマッピングはリストに保存されます。 そのリストは公開されており、 maps 属性を使用してアクセスまたは更新できます。 他の状態はありません。

ルックアップは、キーが見つかるまで、基になるマッピングを連続して検索します。 対照的に、書き込み、更新、および削除は、最初のマッピングでのみ機能します。

ChainMap は、参照によって基礎となるマッピングを組み込んでいます。 したがって、基になるマッピングの1つが更新されると、それらの変更は ChainMap に反映されます。

通常の辞書メソッドはすべてサポートされています。 さらに、 maps 属性、新しいサブコンテキストを作成するためのメソッド、および最初のマッピングを除くすべてにアクセスするためのプロパティがあります。

maps

ユーザーが更新可能なマッピングのリスト。 リストは、最初に検索されたものから最後に検索されたものの順に並べられています。 これは唯一の保存された状態であり、検索するマッピングを変更するために変更できます。 リストには常に少なくとも1つのマッピングが含まれている必要があります。

new_child(m=None)

新しいマップとそれに続く現在のインスタンスのすべてのマップを含む新しい ChainMap を返します。 mを指定すると、マッピングリストの先頭にある新しいマップになります。 指定しない場合、空のdictが使用されるため、d.new_child()の呼び出しはChainMap({}, *d.maps)と同等です。 このメソッドは、親マッピングの値を変更せずに更新できるサブコンテキストを作成するために使用されます。

バージョン3.4で変更:オプションのmパラメーターが追加されました。

parents

最初のインスタンスを除く現在のインスタンスのすべてのマップを含む新しい ChainMap を返すプロパティ。 これは、検索の最初のマップをスキップする場合に役立ちます。 ユースケースは、ネストされたスコープで使用される nonlocal キーワードのユースケースと同様です。 ユースケースは、組み込みの super()関数のユースケースにも対応しています。 d.parentsへの参照は、ChainMap(*d.maps[1:])と同等です。

も参照してください


8.3.1.1。 チェーンマップ例とレシピ

このセクションでは、チェーンマップを操作するためのさまざまなアプローチを示します。

Pythonの内部ルックアップチェーンをシミュレートする例:

import builtins
pylookup = ChainMap(locals(), globals(), vars(builtins))

ユーザー指定のコマンドライン引数を環境変数よりも優先させ、環境変数をデフォルト値よりも優先させる例:

import os, argparse

defaults = {'color': 'red', 'user': 'guest'}

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace = parser.parse_args()
command_line_args = {k:v for k, v in vars(namespace).items() if v}

combined = ChainMap(command_line_args, os.environ, defaults)
print(combined['color'])
print(combined['user'])

ChainMap クラスを使用してネストされたコンテキストをシミュレートするためのパターンの例:

c = ChainMap()        # Create root context
d = c.new_child()     # Create nested child context
e = c.new_child()     # Child of c, independent from d
e.maps[0]             # Current context dictionary -- like Python's locals()
e.maps[-1]            # Root context -- like Python's globals()
e.parents             # Enclosing context chain -- like Python's nonlocals

d['x']                # Get first key in the chain of contexts
d['x'] = 1            # Set value in current context
del d['x']            # Delete from current context
list(d)               # All nested values
k in d                # Check all nested values
len(d)                # Number of nested values
d.items()             # All nested items
dict(d)               # Flatten into a regular dictionary

ChainMap クラスは、チェーン内の最初のマッピングに対してのみ更新(書き込みと削除)を行いますが、ルックアップはチェーン全体を検索します。 ただし、深い書き込みと削除が必要な場合は、チェーンのより深い位置にあるキーを更新するサブクラスを簡単に作成できます。

class DeepChainMap(ChainMap):
    'Variant of ChainMap that allows direct updates to inner scopes'

    def __setitem__(self, key, value):
        for mapping in self.maps:
            if key in mapping:
                mapping[key] = value
                return
        self.maps[0][key] = value

    def __delitem__(self, key):
        for mapping in self.maps:
            if key in mapping:
                del mapping[key]
                return
        raise KeyError(key)

>>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})
>>> d['lion'] = 'orange'         # update an existing key two levels down
>>> d['snake'] = 'red'           # new keys get added to the topmost dict
>>> del d['elephant']            # remove an existing key one level down
>>> d                            # display result
DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})

8.3.2。 カウンターオブジェクト

便利で迅速な集計をサポートするためのカウンターツールが用意されています。 例えば:

>>> # Tally occurrences of words in a list
>>> cnt = Counter()
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
...     cnt[word] += 1
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})

>>> # Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
class collections.Counter([iterable-or-mapping])

Counter は、ハッシュ可能なオブジェクトをカウントするための dict サブクラスです。 これは、要素がディクショナリキーとして格納され、それらのカウントがディクショナリ値として格納される順序付けられていないコレクションです。 カウントは、ゼロまたは負のカウントを含む任意の整数値にすることができます。 Counter クラスは、他の言語のバッグまたはマルチセットに似ています。

要素は iterable からカウントされるか、別のマッピング(またはカウンター)から初期化されます。

>>> c = Counter()                           # a new, empty counter
>>> c = Counter('gallahad')                 # a new counter from an iterable
>>> c = Counter({'red': 4, 'blue': 2})      # a new counter from a mapping
>>> c = Counter(cats=4, dogs=8)             # a new counter from keyword args

カウンターオブジェクトには、 KeyError を発生させる代わりに、欠落しているアイテムに対してゼロカウントを返すことを除いて、ディクショナリインターフェイスがあります。

>>> c = Counter(['eggs', 'ham'])
>>> c['bacon']                              # count of a missing element is zero
0

カウントをゼロに設定しても、要素はカウンターから削除されません。 delを使用して、完全に削除します。

>>> c['sausage'] = 0                        # counter entry with a zero count
>>> del c['sausage']                        # del actually removes the entry

バージョン3.1の新機能。

カウンターオブジェクトは、すべてのディクショナリで使用可能なメソッド以外に、次の3つのメソッドをサポートします。

elements()

それぞれをそのカウントと同じ回数繰り返す要素に対してイテレータを返します。 要素は任意の順序で返されます。 要素の数が1未満の場合、 elements()はそれを無視します。

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> sorted(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
most_common([n])

n の最も一般的な要素とその数のリストを最も一般的なものから最も少ないものへと返します。 n を省略した場合、またはNoneの場合、 most_common()はカウンター内のすべての要素を返します。 カウントが等しい要素は任意に順序付けられます。

>>> Counter('abracadabra').most_common(3)  
[('a', 5), ('r', 2), ('b', 2)]
subtract([iterable-or-mapping])

要素は、 iterable または別の mapping (またはカウンター)から減算されます。 dict.update()と同様ですが、カウントを置き換えるのではなく減算します。 入力と出力の両方がゼロまたは負の場合があります。

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

バージョン3.2の新機能。

通常のディクショナリメソッドは、 Counter オブジェクトで使用できますが、2つはカウンターで異なる動作をします。

fromkeys(iterable)

このクラスメソッドは、 Counter オブジェクトには実装されていません。

update([iterable-or-mapping])

要素は、 iterable からカウントされるか、別のマッピング(またはカウンター)から追加されます。 dict.update()と同様ですが、カウントを置き換える代わりに追加します。 また、 iterable は、(key, value)ペアのシーケンスではなく、要素のシーケンスであることが期待されます。

Counter オブジェクトを操作するための一般的なパターン:

sum(c.values())                 # total of all counts
c.clear()                       # reset all counts
list(c)                         # list unique elements
set(c)                          # convert to a set
dict(c)                         # convert to a regular dictionary
c.items()                       # convert to a list of (elem, cnt) pairs
Counter(dict(list_of_pairs))    # convert from a list of (elem, cnt) pairs
c.most_common()[:-n-1:-1]       # n least common elements
+c                              # remove zero and negative counts

Counter オブジェクトを組み合わせてマルチセット(カウントがゼロより大きいカウンター)を生成するために、いくつかの数学演算が提供されています。 加算と減算は、対応する要素のカウントを加算または減算することによってカウンターを結合します。 共通部分と和集合は、対応するカウントの最小値と最大値を返します。 各操作は、符号付きカウントの入力を受け入れることができますが、出力は、カウントが0以下の結果を除外します。

>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d                       # add two counters together:  c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d                       # subtract (keeping only positive counts)
Counter({'a': 2})
>>> c & d                       # intersection:  min(c[x], d[x]) 
Counter({'a': 1, 'b': 1})
>>> c | d                       # union:  max(c[x], d[x])
Counter({'a': 3, 'b': 2})

単項加算と減算は、空のカウンターを追加したり、空のカウンターから減算したりするためのショートカットです。

>>> c = Counter(a=2, b=-4)
>>> +c
Counter({'a': 2})
>>> -c
Counter({'b': 4})

バージョン3.3の新機能:単項プラス、単項マイナス、およびインプレース多重集合演算のサポートが追加されました。


ノート

カウンターは主に、実行中のカウントを表すために正の整数で機能するように設計されました。 ただし、他のタイプまたは負の値を必要とするユースケースを不必要に排除しないように注意が払われました。 これらのユースケースを支援するために、このセクションでは最小範囲とタイプの制限について説明します。

  • Counter クラス自体は、キーと値に制限のない辞書サブクラスです。 値はカウントを表す数値であることが意図されていますが、値フィールドに何かをできます
  • most_common()メソッドでは、値が順序付け可能である必要があるだけです。
  • c[key] += 1などのインプレース演算の場合、値型は加算と減算のみをサポートする必要があります。 したがって、分数、浮動小数点数、および小数が機能し、負の値がサポートされます。 同じことがupdate()subtract()にも当てはまり、入力と出力の両方に負の値とゼロの値を許可します。
  • マルチセットメソッドは、正の値を持つユースケース専用に設計されています。 入力は負またはゼロの場合がありますが、正の値の出力のみが作成されます。 タイプの制限はありませんが、値タイプは加算、減算、および比較をサポートする必要があります。
  • elements()メソッドには、整数カウントが必要です。 ゼロカウントと負のカウントは無視されます。


も参照してください

  • Smalltalkのバッグクラス

  • マルチセットのウィキペディアエントリ。

  • C ++マルチセットチュートリアルと例。

  • マルチセットの数学演算とその使用例については、を参照してください。 クヌース、ドナルド。 Art of Computer Programming Volume II、セクション4.6.3、演習19 。

  • 特定の要素セットに対する特定のサイズのすべての個別のマルチセットを列挙するには、 itertools.combinations_with_replacement()を参照してください。

    map(Counter、combinations_with_replacement( 'ABC'、2))–> AA AB AC BB BC CC


8.3.3。 deque オブジェクト

class collections.deque([iterable[, maxlen]])

iterable からのデータを使用して( append()を使用して)左から右に初期化された新しいdequeオブジェクトを返します。 iterable が指定されていない場合、新しい両端キューは空です。

Dequesは、スタックとキューを一般化したものです(名前は「deck」と発音され、「両端キュー」の略です)。 Dequeは、スレッドセーフでメモリ効率の高い追加と、Dequeの両側からのポップをサポートし、どちらの方向でもほぼ同じO(1)パフォーマンスを実現します。

list オブジェクトは同様の操作をサポートしますが、高速の固定長操作用に最適化されており、pop(0)およびinsert(0, v)操作の両方を変更するO(n)メモリ移動コストが発生します。基になるデータ表現のサイズと位置。

maxlen が指定されていないか、Noneの場合、両端キューは任意の長さに拡大する可能性があります。 それ以外の場合、両端キューは指定された最大長に制限されます。 制限された長さの両端キューがいっぱいになると、新しいアイテムが追加されると、対応する数のアイテムが反対側から破棄されます。 有界長の両端キューは、Unixのtailフィルターと同様の機能を提供します。 また、最新のアクティビティのみが対象となるトランザクションやその他のデータプールを追跡する場合にも役立ちます。

Dequeオブジェクトは、次のメソッドをサポートします。

append(x)

x を両端キューの右側に追加します。

appendleft(x)

x を両端キューの左側に追加します。

clear()

dequeからすべての要素を削除し、長さ0のままにします。

copy()

dequeの浅いコピーを作成します。

バージョン3.5の新機能。

count(x)

x に等しい両端キュー要素の数を数えます。

バージョン3.2の新機能。

extend(iterable)

iterable引数から要素を追加して、両端キューの右側を拡張します。

extendleft(iterable)

iterable の要素を追加して、両端キューの左側を拡張します。 一連の左追加により、反復可能な引数の要素の順序が逆になることに注意してください。

index(x[, start[, stop]])

deque内の x の位置を返します(インデックス start 以降、インデックス stop の前)。 最初の一致を返すか、見つからない場合は ValueError を発生させます。

バージョン3.5の新機能。

insert(i, x)

xi の位置の両端キューに挿入します。

挿入によって有界両端キューが maxlen を超えて大きくなる場合、 IndexError が発生します。

バージョン3.5の新機能。

pop()

dequeの右側から要素を削除して返します。 要素が存在しない場合、 IndexError が発生します。

popleft()

dequeの左側から要素を削除して返します。 要素が存在しない場合、 IndexError が発生します。

remove(value)

value の最初の出現を削除します。 見つからない場合は、 ValueError を発生させます。

reverse()

dequeの要素をインプレースで反転してから、Noneを返します。

バージョン3.2の新機能。

rotate(n=1)

deque n ステップを右に回転させます。 n が負の場合は、左に回転します。

dequeが空でない場合、右に1ステップ回転するとd.appendleft(d.pop())に相当し、左に1ステップ回転するとd.append(d.popleft())に相当します。

Dequeオブジェクトは、1つの読み取り専用属性も提供します。

maxlen

dequeの最大サイズまたは無制限の場合はNone

バージョン3.1の新機能。

上記に加えて、両端キューは、反復、ピクルス、len(d)reversed(d)copy.copy(d)copy.deepcopy(d)in を使用したメンバーシップテストをサポートします。 ]演算子、およびd[-1]などの添え字参照。 インデックス付きアクセスは、両端がO(1)ですが、中央がO(n)になります。 高速ランダムアクセスの場合は、代わりにリストを使用してください。

バージョン3.5以降、両端キューは__add__()__mul__()、および__imul__()をサポートします。

例:

>>> from collections import deque
>>> d = deque('ghi')                 # make a new deque with three items
>>> for elem in d:                   # iterate over the deque's elements
...     print(elem.upper())
G
H
I

>>> d.append('j')                    # add a new entry to the right side
>>> d.appendleft('f')                # add a new entry to the left side
>>> d                                # show the representation of the deque
deque(['f', 'g', 'h', 'i', 'j'])

>>> d.pop()                          # return and remove the rightmost item
'j'
>>> d.popleft()                      # return and remove the leftmost item
'f'
>>> list(d)                          # list the contents of the deque
['g', 'h', 'i']
>>> d[0]                             # peek at leftmost item
'g'
>>> d[-1]                            # peek at rightmost item
'i'

>>> list(reversed(d))                # list the contents of a deque in reverse
['i', 'h', 'g']
>>> 'h' in d                         # search the deque
True
>>> d.extend('jkl')                  # add multiple elements at once
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1)                      # right rotation
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1)                     # left rotation
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])

>>> deque(reversed(d))               # make a new deque in reverse order
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear()                        # empty the deque
>>> d.pop()                          # cannot pop from an empty deque
Traceback (most recent call last):
    File "<pyshell#6>", line 1, in -toplevel-
        d.pop()
IndexError: pop from an empty deque

>>> d.extendleft('abc')              # extendleft() reverses the input order
>>> d
deque(['c', 'b', 'a'])

8.3.3.1。 deque レシピ

このセクションでは、両端キューを操作するためのさまざまなアプローチを示します。

有界長の両端キューは、Unixのtailフィルターと同様の機能を提供します。

def tail(filename, n=10):
    'Return the last n lines of a file'
    with open(filename) as f:
        return deque(f, n)

dequesを使用する別のアプローチは、右に追加して左にポップすることにより、最近追加された要素のシーケンスを維持することです。

def moving_average(iterable, n=3):
    # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0
    # http://en.wikipedia.org/wiki/Moving_average
    it = iter(iterable)
    d = deque(itertools.islice(it, n-1))
    d.appendleft(0)
    s = sum(d)
    for elem in it:
        s += elem - d.popleft()
        d.append(elem)
        yield s / n

rotate()メソッドは、 deque のスライスと削除を実装する方法を提供します。 たとえば、del d[n]の純粋なPython実装は、rotate()メソッドに依存して、ポップされる要素を配置します。

def delete_nth(d, n):
    d.rotate(-n)
    d.popleft()
    d.rotate(n)

deque スライスを実装するには、rotate()を適用する同様のアプローチを使用して、ターゲット要素をdequeの左側に移動します。 popleft()で古いエントリを削除し、extend()で新しいエントリを追加してから、回転を逆にします。 そのアプローチのマイナーなバリエーションで、dupdropswapover、 [などのForthスタイルのスタック操作を簡単に実装できます。 X152X]、rot、およびroll


8.3.4。 defaultdict オブジェクト

class collections.defaultdict([default_factory[, ...]])

新しい辞書のようなオブジェクトを返します。 defaultdict は、組み込みの dict クラスのサブクラスです。 1つのメソッドをオーバーライドし、1つの書き込み可能なインスタンス変数を追加します。 残りの機能は dict クラスの場合と同じであり、ここでは説明していません。

最初の引数は、 default_factory 属性の初期値を提供します。 デフォルトはNoneです。 残りのすべての引数は、キーワード引数を含め、 dict コンストラクターに渡された場合と同じように扱われます。

defaultdict オブジェクトは、標準の dict 操作に加えて、次のメソッドをサポートします。

__missing__(key)

default_factory 属性がNoneの場合、 key を引数として KeyError 例外が発生します。

default_factoryNoneでない場合、指定されたキーのデフォルト値を提供するために引数なしで呼び出され、この値はの辞書に挿入されます。 key 、および返されます。

default_factory を呼び出すと例外が発生した場合、この例外は変更されずに伝播されます。

このメソッドは、要求されたキーが見つからない場合、 dict クラスの__getitem__()メソッドによって呼び出されます。 返されるか発生するものはすべて、__getitem__()によって返されるか発生します。

__ missing __()は、__getitem__()以外の操作では呼び出されないことに注意してください。 つまり、get()は、通常の辞書と同様に、 default_factory を使用するのではなく、Noneをデフォルトとして返します。

defaultdict オブジェクトは、次のインスタンス変数をサポートします。

default_factory

この属性は、 __ missing __()メソッドによって使用されます。 最初の引数からコンストラクター(存在する場合)またはNone(存在しない場合)に初期化されます。

8.3.4.1。 defaultdict 例

listdefault_factoryとして使用すると、キーと値のペアのシーケンスをリストの辞書に簡単にグループ化できます。

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

各キーが初めて検出されたとき、そのキーはまだマッピングに含まれていません。 したがって、エントリは、空のリストを返すdefault_factory関数を使用して自動的に作成されます。 次に、list.append()操作は、値を新しいリストに添付します。 キーが再び検出されると、ルックアップは正常に進行し(そのキーのリストを返します)、list.append()操作はリストに別の値を追加します。 この手法は、 dict.setdefault()を使用する同等の手法よりも単純で高速です。

>>> d = {}
>>> for k, v in s:
...     d.setdefault(k, []).append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

default_factoryint に設定すると、 defaultdict がカウントに役立ちます(他の言語のバッグやマルチセットなど)。

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> sorted(d.items())
[('i', 4), ('m', 1), ('p', 2), ('s', 4)]

文字が最初に検出されたとき、その文字はマッピングから欠落しているため、default_factory関数は int()を呼び出して、デフォルトのカウント0を提供します。 次に、インクリメント操作により、各文字のカウントが増加します。

常にゼロを返す関数 int()は、定数関数の特殊なケースです。 定数関数を作成するためのより高速で柔軟な方法は、(ゼロだけでなく)任意の定数値を提供できるラムダ関数を使用することです。

>>> def constant_factory(value):
...     return lambda: value
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
'John ran to <missing>'

default_factoryset に設定すると、 defaultdict がセットの辞書を作成するのに役立ちます。

>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
...     d[k].add(v)
...
>>> sorted(d.items())
[('blue', {2, 4}), ('red', {1, 3})]

8.3.5。 namedtuple() 名前付きフィールドを持つタプルのファクトリ関数

名前付きタプルは、タプル内の各位置に意味を割り当て、より読みやすい自己文書化コードを可能にします。 これらは、通常のタプルが使用されている場所ならどこでも使用でき、位置インデックスの代わりに名前でフィールドにアクセスする機能を追加します。

collections.namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)

typename という名前の新しいタプルサブクラスを返します。 新しいサブクラスは、属性ルックアップによってアクセス可能なフィールドを持ち、インデックス付けと反復が可能なタプルのようなオブジェクトを作成するために使用されます。 サブクラスのインスタンスには、便利なdocstring(typenameとfield_namesを含む)と、タプルの内容をname=value形式でリストする便利な__repr__()メソッドもあります。

field_names は、['x', 'y']などの文字列のシーケンスです。 または、 field_names は、'x y''x, y'のように、各フィールド名を空白やコンマで区切った単一の文字列にすることができます。

アンダースコアで始まる名前を除いて、任意の有効なPython識別子をフィールド名に使用できます。 有効な識別子は文字、数字、およびアンダースコアで構成されますが、数字またはアンダースコアで始まらず、クラスforなどのキーワードにすることはできません。 ] returnglobalpass 、または raise

rename がtrueの場合、無効なフィールド名は自動的に位置名に置き換えられます。 たとえば、['abc', 'def', 'ghi', 'abc']['abc', '_1', 'ghi', '_3']に変換され、キーワードdefと重複するフィールド名abcが削除されます。

verbose がtrueの場合、クラス定義はビルド後に出力されます。 このオプションは古くなっています。 代わりに、_source属性を出力する方が簡単です。

module が定義されている場合、指定されたタプルの__module__属性はその値に設定されます。

名前付きタプルインスタンスにはインスタンスごとの辞書がないため、軽量であり、通常のタプルよりも多くのメモリを必要としません。

バージョン3.1で変更: 名前の変更のサポートが追加されました。

バージョン3.6で変更: verbose および rename パラメーターがキーワードのみの引数になりました。

バージョン3.6で変更: module パラメーターが追加されました。

>>> # Basic example
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(11, y=22)     # instantiate with positional or keyword arguments
>>> p[0] + p[1]             # indexable like the plain tuple (11, 22)
33
>>> x, y = p                # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y               # fields also accessible by name
33
>>> p                       # readable __repr__ with a name=value style
Point(x=11, y=22)

名前付きタプルは、 csv または sqlite3 モジュールによって返される結果タプルにフィールド名を割り当てる場合に特に便利です。

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
    print(emp.name, emp.title)

import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
    print(emp.name, emp.title)

タプルから継承されたメソッドに加えて、名前付きタプルは3つの追加メソッドと2つの属性をサポートします。 フィールド名との競合を防ぐために、メソッド名と属性名はアンダースコアで始まります。

classmethod somenamedtuple._make(iterable)

既存のシーケンスまたは反復可能から新しいインスタンスを作成するクラスメソッド。

>>> t = [11, 22]
>>> Point._make(t)
Point(x=11, y=22)
somenamedtuple._asdict()

フィールド名を対応する値にマップする新しい OrderedDict を返します。

>>> p = Point(x=11, y=22)
>>> p._asdict()
OrderedDict([('x', 11), ('y', 22)])

バージョン3.1で変更:通常の dict の代わりに OrderedDict を返します。

somenamedtuple._replace(**kwargs)

指定されたフィールドを新しい値に置き換えて、名前付きタプルの新しいインスタンスを返します。

>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)

>>> for partnum, record in inventory.items():
...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
somenamedtuple._source

名前付きタプルクラスの作成に使用される純粋なPythonソースコードを含む文字列。 ソースは、名前付きタプルを自己文書化します。 印刷したり、 exec()を使用して実行したり、ファイルに保存してインポートしたりできます。

バージョン3.3の新機能。

somenamedtuple._fields

フィールド名をリストする文字列のタプル。 イントロスペクションや、既存の名前付きタプルから新しい名前付きタプルタイプを作成する場合に便利です。

>>> p._fields            # view the field names
('x', 'y')

>>> Color = namedtuple('Color', 'red green blue')
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)

名前が文字列に格納されているフィールドを取得するには、 getattr()関数を使用します。

>>> getattr(p, 'x')
11

辞書を名前付きタプルに変換するには、double-star-operatorを使用します(引数リストの解凍で説明されています)。

>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)

名前付きタプルは通常のPythonクラスであるため、サブクラスを使用して機能を簡単に追加または変更できます。 計算フィールドと固定幅の印刷形式を追加する方法は次のとおりです。

>>> class Point(namedtuple('Point', ['x', 'y'])):
...     __slots__ = ()
...     @property
...     def hypot(self):
...         return (self.x ** 2 + self.y ** 2) ** 0.5
...     def __str__(self):
...         return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

>>> for p in Point(3, 4), Point(14, 5/7):
...     print(p)
Point: x= 3.000  y= 4.000  hypot= 5.000
Point: x=14.000  y= 0.714  hypot=14.018

上記のサブクラスは、__slots__を空のタプルに設定します。 これは、インスタンスディクショナリの作成を防ぐことにより、メモリ要件を低く抑えるのに役立ちます。

サブクラス化は、新しい保存済みフィールドの追加には役立ちません。 代わりに、_fields属性から新しい名前付きタプルタイプを作成するだけです。

>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))

Docstringは、__doc__フィールドに直接割り当てることでカスタマイズできます。

>>> Book = namedtuple('Book', ['id', 'title', 'authors'])
>>> Book.__doc__ += ': Hardcover book in active collection'
>>> Book.id.__doc__ = '13-digit ISBN'
>>> Book.title.__doc__ = 'Title of first printing'
>>> Book.authors.__doc__ = 'List of authors sorted by last name'

バージョン3.5で変更:プロパティdocstringが書き込み可能になりました。


_replace()を使用してプロトタイプインスタンスをカスタマイズすることにより、デフォルト値を実装できます。

>>> Account = namedtuple('Account', 'owner balance transaction_count')
>>> default_account = Account('<owner name>', 0.0, 0)
>>> johns_account = default_account._replace(owner='John')
>>> janes_account = default_account._replace(owner='Jane')

も参照してください


8.3.6。 OrderedDict オブジェクト

順序付けられた辞書は通常の辞書と同じですが、アイテムが挿入された順序を覚えています。 順序付けられた辞書を反復処理すると、キーが最初に追加された順序でアイテムが返されます。

class collections.OrderedDict([items])

通常の dict メソッドをサポートするdictサブクラスのインスタンスを返します。 OrderedDict は、キーが最初に挿入された順序を記憶するdictです。 新しいエントリが既存のエントリを上書きする場合、元の挿入位置は変更されません。 エントリを削除して再挿入すると、最後に移動します。

バージョン3.1の新機能。

popitem(last=True)

順序付けられた辞書の popitem()メソッドは、(キー、値)ペアを返したり削除したりします。 ペアは、 last がtrueの場合は LIFO の順序で返され、falseの場合は FIFO の順序で返されます。

move_to_end(key, last=True)

既存のキーを順序付けられた辞書の両端に移動します。 last がtrue(デフォルト)の場合は右端に移動し、 last がfalseの場合は先頭に移動します。 key が存在しない場合、 KeyError を発生させます。

>>> d = OrderedDict.fromkeys('abcde')
>>> d.move_to_end('b')
>>> ''.join(d.keys())
'acdeb'
>>> d.move_to_end('b', last=False)
>>> ''.join(d.keys())
'bacde'

バージョン3.2の新機能。

通常のマッピング方法に加えて、順序付けされた辞書は、 reverse()を使用した逆反復もサポートします。

OrderedDict オブジェクト間の同等性テストは順序に依存し、list(od1.items())==list(od2.items())として実装されます。 OrderedDict オブジェクトと他の Mapping オブジェクト間の同等性テストは、通常の辞書のように順序に依存しません。 これにより、 OrderedDict オブジェクトを、通常の辞書が使用されている場所ならどこでも置き換えることができます。

バージョン3.5で変更: OrderedDict のアイテム、キー、および値ビューは、 reverse()を使用した逆反復をサポートするようになりました。


バージョン3.6で変更: PEP 468 の受け入れにより、 OrderedDict コンストラクターとその[ X178X] メソッド。


8.3.6.1。 OrderedDict 例とレシピ

順序付けされた辞書はその挿入順序を記憶しているため、並べ替えと組み合わせて使用して、並べ替えられた辞書を作成できます。

>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}

>>> # dictionary sorted by key
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

新しくソートされた辞書は、エントリが削除されてもソート順を維持します。 ただし、新しいキーが追加されると、キーは最後に追加され、並べ替えは維持されません。

キーが最後に挿入された順序を記憶する順序付き辞書バリアントを作成することも簡単です。 新しいエントリが既存のエントリを上書きする場合、元の挿入位置が変更され、最後に移動されます。

class LastUpdatedOrderedDict(OrderedDict):
    'Store items in the order the keys were last added'

    def __setitem__(self, key, value):
        if key in self:
            del self[key]
        OrderedDict.__setitem__(self, key, value)

順序付けされた辞書を Counter クラスと組み合わせて、カウンターが順序要素が最初に検出されたことを記憶するようにすることができます。

class OrderedCounter(Counter, OrderedDict):
    'Counter that remembers the order elements are first encountered'

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

    def __reduce__(self):
        return self.__class__, (OrderedDict(self),)

8.3.7。 UserDict オブジェクト

クラス UserDict は、ディクショナリオブジェクトのラッパーとして機能します。 このクラスの必要性は、 dict から直接サブクラス化する機能に部分的に取って代わられました。 ただし、基になるディクショナリに属性としてアクセスできるため、このクラスの操作は簡単です。

class collections.UserDict([initialdata])

辞書をシミュレートするクラス。 インスタンスのコンテンツは通常の辞書に保存されており、 UserDict インスタンスの data 属性を介してアクセスできます。 initialdata が指定されている場合、 data はその内容で初期化されます。 initialdata への参照は保持されないため、他の目的に使用できることに注意してください。

UserDict インスタンスは、マッピングのメソッドと操作をサポートすることに加えて、次の属性を提供します。

data

UserDict クラスの内容を格納するために使用される実際の辞書。


8.3.8。 UserList オブジェクト

このクラスは、リストオブジェクトのラッパーとして機能します。 これは、リストから継承して既存のメソッドをオーバーライドしたり、新しいメソッドを追加したりできる、独自のリストのようなクラスの便利な基本クラスです。 このようにして、リストに新しい動作を追加できます。

このクラスの必要性は、リストから直接サブクラス化する機能に部分的に取って代わられました。 ただし、基になるリストに属性としてアクセスできるため、このクラスの操作は簡単です。

class collections.UserList([list])

リストをシミュレートするクラス。 インスタンスのコンテンツは通常のリストに保持され、 UserList インスタンスの data 属性を介してアクセスできます。 インスタンスのコンテンツは、最初は list のコピーに設定され、デフォルトでは空のリスト[]に設定されます。 list は、実際のPythonリストや UserList オブジェクトなど、任意の反復可能にすることができます。

UserList インスタンスは、可変シーケンスのメソッドと操作をサポートすることに加えて、次の属性を提供します。

data

UserList クラスのコンテンツを格納するために使用される実際の list オブジェクト。

サブクラス化の要件: UserList のサブクラスは、引数なしまたは1つの引数で呼び出すことができるコンストラクターを提供することが期待されています。 新しいシーケンスを返すリスト操作は、実際の実装クラスのインスタンスを作成しようとします。 そのために、コンストラクターは、データソースとして使用されるシーケンスオブジェクトである単一のパラメーターで呼び出すことができると想定しています。

派生クラスがこの要件に準拠することを望まない場合は、このクラスでサポートされているすべての特別なメソッドをオーバーライドする必要があります。 その場合に提供する必要のある方法については、情報源を参照してください。


8.3.9。 UserString オブジェクト

クラス UserString は、文字列オブジェクトのラッパーとして機能します。 このクラスの必要性は、 str から直接サブクラス化する機能に部分的に取って代わられました。 ただし、基になる文字列に属性としてアクセスできるため、このクラスの操作は簡単です。

class collections.UserString([sequence])

文字列またはUnicode文字列オブジェクトをシミュレートするクラス。 インスタンスのコンテンツは通常の文字列オブジェクトに保持され、 UserString インスタンスのdata属性を介してアクセスできます。 インスタンスの内容は、最初はシーケンスのコピーに設定されています。 sequence は、 bytesstrUserString (またはサブクラス)のインスタンス、またはに変換できる任意のシーケンスにすることができます。組み込みの str()関数を使用する文字列。

バージョン3.5で変更:新しいメソッド__getnewargs____rmod__casefoldformat_mapisprintable、および[ X104X] 。