"collections" --- コンテナデータ型
**********************************

**ソースコード:** Lib/collections/__init__.py

======================================================================

このモジュールは、汎用の Python 組み込みコンテナ "dict", "list",
"set", および "tuple" に代わる、特殊なコンテナデータ型を実装しています
。

+-----------------------+----------------------------------------------------------------------+
| "namedtuple()"        | 名前付きフィールドを持つタプルのサブクラスを作成するファクトリ関数   |
+-----------------------+----------------------------------------------------------------------+
| "deque"               | 両端における append や pop を高速に行えるリスト風のコンテナ          |
+-----------------------+----------------------------------------------------------------------+
| "ChainMap"            | 複数のマッピングの一つのビューを作成する辞書風のクラス               |
+-----------------------+----------------------------------------------------------------------+
| "Counter"             | ハッシュ可能なオブジェクトを数え上げる辞書のサブクラス               |
+-----------------------+----------------------------------------------------------------------+
| "OrderedDict"         | 項目が追加された順序を記憶する辞書のサブクラス                       |
+-----------------------+----------------------------------------------------------------------+
| "defaultdict"         | ファクトリ関数を呼び出して存在しない値を供給する辞書のサブクラス     |
+-----------------------+----------------------------------------------------------------------+
| "UserDict"            | 辞書のサブクラス化を簡単にする辞書オブジェクトのラッパ               |
+-----------------------+----------------------------------------------------------------------+
| "UserList"            | リストのサブクラス化を簡単にするリストオブジェクトのラッパ           |
+-----------------------+----------------------------------------------------------------------+
| "UserString"          | 文字列のサブクラス化を簡単にする文字列オブジェクトのラッパ           |
+-----------------------+----------------------------------------------------------------------+

Deprecated since version 3.3, will be removed in version 3.10: コレク
ション抽象基底クラス が "collections.abc" モジュールに移動されました。
後方互換性のため、それらは引き続きPython 3.9モジュールでも利用できます
。


"ChainMap" オブジェクト
=======================

バージョン 3.3 で追加.

"ChainMap" クラスは、複数のマッピングを素早く連結し、一つの単位として
扱うために提供されています。これはたいてい、新しい辞書を作成して
"update()" を繰り返すよりも早いです。

このクラスはネストされたスコープをシミュレートするのに使え、テンプレー
ト化に便利です。

class collections.ChainMap(*maps)

   "ChainMap" は、複数の辞書やその他のマッピングをまとめて、一つの、更
   新可能なビューを作成します。 *maps* が指定されないなら、一つの空辞
   書が与えられますから、新しいチェーンは必ず一つ以上のマッピングをも
   ちます。

   根底のマッピングはリストに保存されます。このリストはパブリックで、
   *maps* 属性を使ってアクセスや更新できます。それ以外に状態はありませ
   ん。

   探索は、根底のマッピングをキーが見つかるまで引き続き探します。対し
   て、書き込み、更新、削除は、最初のマッピングのみ操作します。

   "ChainMap" は、根底のマッピングを参照によって組み込みます。ですから
   、根底のマッピングの一つが更新されると、その変更は "ChainMap" に反
   映されます。

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

   maps

      マッピングのユーザがアップデートできるリストです。このリストは最
      初に探されるものから最後に探されるものの順に並んでいます。これが
      唯一のソートされた状態であり、変更してマッピングが探される順番を
      変更できます。このリストは常に一つ以上のマッピングを含んでいなけ
      ればなりません。

   new_child(m=None)

      新しい辞書の後ろに現在のインスタンスにある全ての辞書が続いたもの
      を持つ、新しい "ChainMap" を返します。 "m" が指定された場合、そ
      れがマッピングのリストの先頭の新しい辞書になります; 指定されてい
      ない場合、 "d.new_child()" が "ChainMap({}, *d.maps)" と同等とな
      るように空の辞書が使われます。このメソッドは、親マッピングを変更
      することなく値を更新できるサブコンテキストを作成するのに使われま
      す。

      バージョン 3.4 で変更: オプションの "m" 引数が追加されました。

   parents

      現在のインスタンスの最初のマッピング以外のすべてのマッピングを含
      む新しい "ChainMap" を返すプロパティです。これは最初のマッピング
      を検索から飛ばすのに便利です。使用例は "nonlocal" キーワードを *
      ネストされたスコープ* に使う例と似ています。この使用例はまた、組
      み込み "super()" 関数にも似ています。 "d.parents" への参照は
      "ChainMap(*d.maps[1:])" と等価です。

   "ChainMap()" の反復順序は、マッピングオブジェクトを末尾から先頭に向
   かう走査で決まることに注意してください。

      >>> baseline = {'music': 'bach', 'art': 'rembrandt'}
      >>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}
      >>> list(ChainMap(adjustments, baseline))
      ['music', 'art', 'opera']

   これは、末尾のマッピングオブジェクトから始めた一連の
   "dict.update()" の呼び出しと同じ順序になります。

      >>> combined = baseline.copy()
      >>> combined.update(adjustments)
      >>> list(combined)
      ['music', 'art', 'opera']

   バージョン 3.9 で変更: **PEP 584** で規定されている "|" 演算子と
   "|=" 演算子のサポートを追加しました。

参考:

  * Enthought 社の CodeTools パッケージ に含まれる MultiContext クラス
    は、チェーン内のすべてのマッピングへの書き込みをサポートするオプシ
    ョンを持ちます。

  * Django のテンプレート用の *Context class `_ は、読み出し専用のマッ
    ピングのチェーンです。 :meth:`~collections.ChainMap.new_child* メ
    ソッドや "parents" プロパティに似た push や pop の機能もあります。

  * Nested Contexts recipe は、書き込みその他の変更が最初のマッピング
    にのみ適用されるか、チェーンのすべてのマッピングに適用されるか、制
    御するオプションを持ちます。

  * 非常に単純化した読み出し専用バージョンの Chainmap。


"ChainMap" の例とレシピ
-----------------------

この節では、チェーンされたマッピングを扱う様々な手法を示します。

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 is not None}

   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'] = 1            # Set value in current context
   d['x']                # Get first key in the chain of contexts
   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'})


"Counter" オブジェクト
======================

便利で迅速な検数をサポートするカウンタツールが提供されています。例えば
:

   >>> # 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" のサブ
   クラスです。これは、要素を辞書のキーとして保存し、そのカウントを辞
   書の値として保存するコレクションです。カウントは、0 や負のカウント
   を含む整数値をとれます。 "Counter" クラスは、他の言語のバッグや多重
   集合のようなものです。

   要素は、 *iterable* から数え上げられたり、他の *mapping* (やカウン
   タ) から初期化されます:

   >>> 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" を送出する代わりに 0 を返すという違いがあ
   ります:

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

   カウントを 0 に設定しても、要素はカウンタから取り除かれません。完全
   に取り除くには、 "del" を使ってください:

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

   バージョン 3.1 で追加.

   バージョン 3.7 で変更: "Counter" は class:*dict* のサブクラスとして
   要素の挿入順を維持する機能を継承しました。 *Counter* オブジェクトに
   対する数学演算も順序を維持します。結果は左の被演算子で最初に要素が
   出現するあとに、右の被演算子で要素が出現する順序になります。

   Counter objects support additional methods beyond those available
   for all dictionaries:

   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), ('b', 2), ('r', 2)]

   subtract([iterable-or-mapping])

      要素から *iterable* の要素または *mapping* の要素が引かれます。
      "dict.update()" に似ていますが、カウントを置き換えるのではなく引
      きます。入力も出力も、 0 や負になりえます。

      >>> 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 で追加.

   普通の辞書のメソッドは、以下の 2 つのメソッドがカウンタに対して異な
   る振る舞いをするのを除き、 "Counter" オブジェクトにも利用できます。

   fromkeys(iterable)

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

   update([iterable-or-mapping])

      要素が *iterable* からカウントされるか、別の *mapping* (やカウン
      タ) が追加されます。 "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" オブジェクトを組み合わせて多重集合 (1 以上のカウントをもつカ
ウンタ) を作るために、いくつかの数学演算が提供されています。足し算と引
き算は、対応する要素を足したり引いたりすることによってカウンタを組み合
わせます。積集合と和集合は、対応するカウントの最大値と最小値を返します
。それぞれの演算はカウントに符号がついた入力を受け付けますが、カウント
が 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 で追加: 単項加算、単項減算、in-place の多重集合操作のサ
ポートが追加されました。

注釈:

  カウンタはもともと、推移するカウントを正の整数で表すために設計されま
  した。しかし、他の型や負の値を必要とするユースケースを不必要に排除す
  ることがないように配慮されています。このようなユースケースの助けにな
  るように、この節で最低限の範囲と型の制限について記述します。

  * "Counter" クラス自体は辞書のサブクラスで、キーと値に制限はありませ
    ん。値はカウントを表す数であることを意図していますが、値フィールド
    に任意のものを保存 *できます* 。

  * "most_common()" メソッドが要求するのは、値が順序付け可能なことだけ
    です。

  * "c[key] += 1" のようなインプレース演算では、値の型に必要なのは 足
    し算と引き算ができることだけです。よって分数、浮動小数点数、 小数
    も使え、負の値がサポートされています。これと同じことが、 負や 0 の
    値を入力と出力に許す "update()" と "subtract()" メソッド にも言え
    ます。

  * 多重集合メソッドは正の値を扱うユースケースに対してのみ設計されてい
    ます。入力は負や 0 に出来ますが、正の値の出力のみが生成されます。
    型の制限はありませんが、値の型は足し算、引き算、比較をサポートして
    いる必要があります。

  * "elements()" メソッドは整数のカウントを要求します。これは 0 と負の
    カウントを無視します。

参考:

  * Smalltalk の Bag class 。

  * Wikipedia の Multisets の項目。

  * C++ multisets の例を交えたチュートリアル。

  * 数学的な多重集合の演算とそのユースケースは、 *Knuth, Donald. The
    Art of Computer Programming Volume II, Section 4.6.3, Exercise 19*
    を参照してください。

  * 与えられた要素の集まりからなる与えられた大きさの相違なる多重集合を
    すべて数え上げるには、 "itertools.combinations_with_replacement()"
    を参照してください:

       map(Counter, combinations_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC


"deque" オブジェクト
====================

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

   *iterable* で与えられるデータから、新しい deque オブジェクトを
   ("append()" をつかって) 左から右に初期化して返します。 *iterable*
   が指定されない場合、新しい deque オブジェクトは空になります。

   Deque とは、スタックとキューを一般化したものです (この名前は「デッ
   ク」と発音され、これは「double-ended queue」の省略形です)。Deque は
   どちらの側からも append と pop が可能で、スレッドセーフでメモリ効率
   がよく、どちらの方向からもおよそ "O(1)" のパフォーマンスで実行でき
   ます。

   "list" オブジェクトでも同様の操作を実現できますが、これは高速な固定
   長の操作に特化されており、内部のデータ表現形式のサイズと位置を両方
   変えるような "pop(0)" や "insert(0, v)" などの操作ではメモリ移動の
   ために "O(n)" のコストを必要とします。

   *maxlen* が指定されなかったり "None" だった場合、 deque は任意のサ
   イズまで大きくなります。 そうでない場合、 deque のサイズは指定され
   た最大長に制限されます。 長さが制限された deque がいっぱいになると
   、新しい要素を追加するときに追加した要素数分だけ追加したのと反対側
   から要素が捨てられます。 長さが制限された deque は Unix における
   "tail" フィルタと似た機能を提供します。 トランザクションの tracking
   や最近使った要素だけを残したいデータプール (pool of data) などにも
   便利です。

   Deque オブジェクトは以下のようなメソッドをサポートしています:

   append(x)

      *x* を deque の右側につけ加えます。

   appendleft(x)

      *x* を deque の左側につけ加えます。

   clear()

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

   copy()

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

      バージョン 3.5 で追加.

   count(x)

      deque の *x* に等しい要素を数え上げます。

      バージョン 3.2 で追加.

   extend(iterable)

      イテラブルな引数 iterable から得られる要素を deque の右側に追加
      し拡張します。

   extendleft(iterable)

      イテラブルな引数 iterable から得られる要素を deque の左側に追加
      し拡張します。注意: 左から追加した結果は、イテラブルな引数の順序
      とは逆になります。

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

      deque 内の *x* の位置を返します (インデックス *start* からインデ
      ックス *stop* の両端を含む範囲で)。最初のマッチを返すか、見つか
      らない場合には "ValueError" を発生させます。

      バージョン 3.5 で追加.

   insert(i, x)

      *x* を deque の位置 *i* に挿入します。

      挿入によって、長さに制限のある deque の長さが *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 が空でないときは、 deque をひとつ右にローテートすることは
      "d.appendleft(d.pop())" と同じで、 deque をひとつ左にローテート
      することは "d.append(d.popleft())" と同じです。

   deque オブジェクトは読み出し専用属性も 1 つ提供しています:

   maxlen

      deque の最大長で、制限されていなければ "None" です。

      バージョン 3.1 で追加.

上記に加え、 deque はイテレーション, pickle 化, "len(d)",
"reversed(d)", "copy.copy(d)", "copy.deepcopy(d)", "in" 演算子による包
含の検査,  "d[0]" のような添字による参照をサポートしています。添字によ
るアクセスは、両端の要素では O(1) ですが、中央部分の要素では O(n) と遅
くなります。高速なランダムアクセスのためには、代わりにリストを使ってく
ださい。

バージョン 3.5 から deque は "__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'])


"deque" のレシピ
----------------

この節では deque を使った様々なアプローチを紹介します。

長さが制限された 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)

deque  を使用する別のアプローチは、右に要素を追加し左から要素を取り出
すことで最近追加した要素のシーケンスを保持することです:

   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

ラウンドロビンスケジューラ は、入力されたイテレータを "deque" に格納す
ることで実装できます。 値は、位置0にある選択中のイテレータから取り出さ
れます。 そのイテレータが値を出し切った場合は、 "popleft()" で除去でき
ます; そうでない場合は、 "rotate()" メソッドで末尾に回せます:

   def roundrobin(*iterables):
       "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
       iterators = deque(map(iter, iterables))
       while iterators:
           try:
               while True:
                   yield next(iterators[0])
                   iterators.rotate(-1)
           except StopIteration:
               # Remove an exhausted iterator.
               iterators.popleft()

"rotate()" メソッドは、 "deque" のスライスや削除の機能を提供します。
例えば、 純粋な Python 実装の "del d[n]" は "rotate()" メソッドを頼り
に、pop される要素の位置を割り出します:

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

"deque" のスライスの実装でも、同様のアプローチを使います。まず対象とな
る要素を "rotate()" によって deque の左端まで移動させてから、
"popleft()" で古い要素を削除します。そして、 "extend()" で新しい要素を
追加したのち、循環を逆にします。このアプローチをやや変えたものとして、
Forth スタイルのスタック操作、つまり "dup", "drop", "swap", "over",
"pick", "rot", および "roll" を実装するのも簡単です。


"defaultdict" オブジェクト
==========================

class collections.defaultdict(default_factory=None, /[, ...])

   新しい辞書に似たオブジェクトを返します。 "defaultdict" は組み込みの
   "dict" クラスのサブクラスです。これはメソッドをひとつオーバーライド
   し、書き込み可能なインスタンス変数をひとつ追加しています。それ以外
   の機能は "dict" クラスと同じですので、ここでは説明しません。

   1つ目の引数は "default_factory" 属性の初期値です。デフォルトは
   "None" です。残りの引数はキーワード引数も含め、 "dict" のコンストラ
   クタに与えられた場合と同様に扱われます。

   "defaultdict" オブジェクトは標準の "dict" に加えて、以下のメソッド
   を実装しています:

   __missing__(key)

      もし "default_factory" 属性が "None" であれば、このメソッドは
      "KeyError" 例外を、 *key* を引数として発生させます。

      もし "default_factory" 属性が "None" でない場合、このメソッドは
      引数なしで呼び出され、与えらえた *key* に対応するデフォルト値を
      提供します。この値は、辞書内に *key* に対応して登録され、最後に
      返されます。

      もし "default_factory" の呼出が例外を発生させた場合には、変更せ
      ずそのまま例外を投げます。

      このメソッドは "dict" クラスの "__getitem__()" メソッドで、キー
      が存在しなかった場合によびだされます。値を返すか例外を発生させる
      のどちらにしても、 "__getitem__()" からもそのまま値が返るか例外
      が発生します。

      なお、 "__missing__()" は "__getitem__()" 以外のいかなる演算に対
      しても呼び出され *ません* 。よって "get()" は、普通の辞書と同様
      に、 "default_factory" を使うのではなくデフォルトとして "None"
      を返します。

   "defaultdict" オブジェクトは以下のインスタンス変数をサポートしてい
   ます:

   default_factory

      この属性は "__missing__()" メソッドによって使われます。これは存
      在すればコンストラクタの第1引数によって初期化され、そうでなけれ
      ば "None" になります。

   バージョン 3.9 で変更: **PEP 584** で規定されている合成演算子 ("|")
   と更新演算子 ("|=")が追加されました。


"defaultdict" の使用例
----------------------

"list" を "default_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" を使って自動
的に作成されます。 "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_factory" を "int" にすると、 "defaultdict" を(他の言語の bag
や multisetのように)要素の数え上げに便利に使うことができます:

>>> 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を生成し
ます。インクリメント操作が各文字を数え上げます。

常に0を返す "int()" は特殊な関数でした。定数を生成するより速くて柔軟な
方法は、 0に限らず何でも定数を生成するラムダ関数を使うことです:

>>> 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_factory" を "set" に設定することで、 "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})]


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

名前付きタプルは、タプルの中のすべての場所に意味を割り当てて、より読み
やすく自己解説的なコードを書けるようにします。通常のタプルが利用される
場所ならどこでも利用でき、場所に対するインデックスの代わりに名前を使っ
てフィールドにアクセスできるようになります。

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

   *typename* という名前の tuple の新しいサブクラスを返します。新しい
   サブクラスは、 tuple に似ているけれどもインデックスやイテレータだけ
   でなく属性名によるアクセスもできるオブジェクトを作るのに使います。
   このサブクラスのインスタンスは、わかりやすい docstring (型名と属性
   名が入っています) や、 tuple の内容を "name=value" という形のリスト
   で返す使いやすい "__repr__()" も持っています。

   *field_names* は "['x', 'y']" のような文字列のシーケンスです。
   *field_names* には、代わりに各属性名を空白文字 (whitespace) および/
   またはカンマ (,) で区切った文字列を渡すこともできます。例えば、 "'x
   y'" や "'x, y'" です。

   アンダースコア (_) で始まる名前を除いて、 Python の正しい識別子
   (identifier) ならなんでも属性名として使うことができます。正しい識別
   子とはアルファベット(letters), 数字(digits), アンダースコア(_) を含
   みますが、数字やアンダースコアで始まる名前や、 *class*, *for*,
   *return*, *global*, *pass*, *raise* などといった "keyword" は使えま
   せん。

   *rename* が真の場合、不適切なフィールド名は自動的に位置を示す名前に
   置き換えられます。例えば "['abc', 'def', 'ghi', 'abc']" は、予約語
   の "def" と、重複しているフィールド名の "abc" が除去され、"['abc',
   '_1', 'ghi', '_3']" に変換されます。

   *defaults* には "None" あるいはデフォルト値の *iterable* が指定でき
   ます。 デフォルト値を持つフィールドはデフォルト値を持たないフィール
   ドより後ろに来なければならないので、 *defaults* は最も右にある変数
   に適用されます。 例えば、 field_names が "['x', 'y', 'z']" で
   defaults が "(1, 2)" の場合、 "x" は必須の引数、 "y" は "1" がデフ
   ォルト、 "z" は "2" がデフォルトとなります。

   もし *module* が指定されていれば、名前付きタプルの "__module__" 属
   性は、指定された値に設定されます

   名前付きタプルのインスタンスはインスタンスごとの辞書を持たないので
   、軽量で、普通のタプル以上のメモリを使用しません。

   pickle 化をサポートするには、名前付きタプルのクラス定義は
   *typename* と同じ名前の変数に割り当てなければなりません。

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

   バージョン 3.6 で変更: *verbose* と *rename* 引数が キーワード専用
   引数 になりました.

   バージョン 3.6 で変更: *module* 引数が追加されました。

   バージョン 3.7 で変更: *verbose* 引数と "_source" 属性が削除されま
   した。

   バージョン 3.7 で変更: *defaults* 引数と "_field_defaults" 属性が追
   加されました。

   >>> # 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)

   既存の sequence や Iterable から新しいインスタンスを作るクラスメソ
   ッド.

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

somenamedtuple._asdict()

   フィールド名を対応する値にマッピングする新しい "dict" を返します:

      >>> p = Point(x=11, y=22)
      >>> p._asdict()
      {'x': 11, 'y': 22}

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

   バージョン 3.8 で変更: "collections.OrderedDict" ではなく "dict" を
   返すようになりました。Python 3.7以降は、通常の辞書で順番が保証され
   ています。 "OrderedDict" 特有の機能を使いたい場合は、結果を
   "OrderedDict(nt._asdict())" 型にキャストして使用することを推奨しま
   す。

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._fields

   フィールド名をリストにしたタプルです。内省 (introspection) したり、
   既存の名前付きタプルをもとに新しい名前つきタプルを作成する時に便利
   です。

      >>> 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)

somenamedtuple._field_defaults

   フィールド名からデフォルト値への対応を持つ辞書です。

      >>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
      >>> Account._field_defaults
      {'balance': 0}
      >>> Account('premium')
      Account(type='premium', balance=0)

文字列に格納された名前を使って名前つきタプルから値を取得するには
"getattr()" 関数を使います:

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

辞書を名前付きタプルに変換するには、 "**" 演算子 (double-star-
operator, 引数リストのアンパック で説明しています) を使います。:

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

名前付きタプルは通常の Python クラスなので、継承して機能を追加したり変
更するのは容易です。次の例では計算済みフィールドと固定幅の print
format を追加しています:

   >>> 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',))

"__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 で変更: 属性ドックストリングが書き込み可能になりました
。

参考:

  * 名前付きタプルに型ヒントを追加する方法については、
    "typing.NamedTuple" を参照してください。 "class" キーワードを使っ
    た洗練された記法も紹介されています:

       class Component(NamedTuple):
           part_number: int
           weight: float
           description: Optional[str] = None

  * タプルではなく、辞書をもとにした変更可能な名前空間を作成するには
    "types.SimpleNamespace()" を参照してください。

  * "dataclasses" モジュールは、生成される特殊メソッドをユーザー定義ク
    ラスに自動的に追加するためのデコレータや関数を提供しています。


"OrderedDict" オブジェクト
==========================

順序付き辞書は普通の辞書のようですが、順序操作に関係する追加の機能があ
ります。 組み込みの "dict" クラスが挿入順序を記憶しておく機能 (この新
しい振る舞いは Python 3.7 で保証されるようになりました) を獲得した今と
なっては、順序付き辞書の重要性は薄れました。

いまだ残っている "dict" との差分:

* 通常の "dict" は対応付けに向いているように設計されました。 挿入順序
  の追跡は二の次です。

* "OrderedDict" は並べ替え操作に向いているように設計されました。 空間
  効率、反復処理の速度、更新操作のパフォーマンスは二の次です。

* アルゴリズム的に、 "OrderedDict" は高頻度の並べ替え操作を "dict" よ
  りも上手く扱えます。 この性質により、 "OrderedDict" は直近のアクセス
  の追跡 (例えば、 LRU キャッシュ) に向いています。

* "OrderedDict" に対する等価演算は突き合わせ順序もチェックします。

* "OrderedDict" の "popitem()" メソッドはシグネチャが異なります。 どの
  要素を取り出すかを指定するオプション引数を受け付けます。

* "OrderedDict" には、 効率的に要素を末尾に置き直す "move_to_end()" メ
  ソッドがあります。

* Python 3.8 以前は、 "dict" には "__reversed__()" メソッドが欠けてい
  ます。

class collections.OrderedDict([items])

   辞書の順序を並べ直すためのメソッドを持つ "dict" のサブクラスのイン
   スタンスを返します。

   バージョン 3.1 で追加.

   popitem(last=True)

      順序付き辞書の "popitem()" メソッドは、(key, value) 対を返して消
      去します。この対は *last* が真なら LIFO (last-in, first-out, 後
      入先出) で、偽なら FIFO (first-in, first-out, 先入先出)  で返さ
      れます。

   move_to_end(key, last=True)

      既存の *key* を順序付き辞書の両端に移動します。項目は、 *last*
      が真 (デフォルト) なら右端に、 *last* が偽なら最初に移動されます
      。 *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 で追加.

通常のマッピングのメソッドに加え、順序付き辞書は "reversed()" による逆
順の反復もサポートしています。

"OrderedDict" 間の等価判定は順序が影響し、
"list(od1.items())==list(od2.items())" のように実装されます。
"OrderedDict" オブジェクトと他のマッピング ("Mapping") オブジェクトの
等価判定は、順序に影響されず、通常の辞書と同様です。これによって、
"OrderedDict" オブジェクトは通常の辞書が使われるところならどこでも使用
できます。

バージョン 3.5 で変更: "OrderedDict" の項目、キー、値の *ビュー* が
"reversed()" による逆順の反復をサポートするようになりました。

バージョン 3.6 で変更: **PEP 468** の受理によって、"OrderedDict" のコ
ンストラクタと、"update()" メソッドに渡したキーワード引数の順序は保持
されます。

バージョン 3.9 で変更: **PEP 584** で規定されている合成演算子 ("|") と
更新演算子 ("|=")が追加されました。


"OrderedDict" の例とレシピ
--------------------------

キーが *最後に* 追加されたときの順序を記憶する、順序付き辞書の変種を作
るのは簡単です。 新しい値が既存の値を上書きする場合、元々の挿入位置が
最後尾へ変更されます:

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

       def __setitem__(self, key, value):
           super().__setitem__(key, value)
           self.move_to_end(key)

"OrderedDict" は "functools.lru_cache()" の変種を実装するのにも役に立
ちます:

   class LRU:

       def __init__(self, func, maxsize=128):
           self.func = func
           self.maxsize = maxsize
           self.cache = OrderedDict()

       def __call__(self, *args):
           if args in self.cache:
               value = self.cache[args]
               self.cache.move_to_end(args)
               return value
           value = self.func(*args)
           if len(self.cache) >= self.maxsize:
               self.cache.popitem(False)
           self.cache[args] = value
           return value


"UserDict" オブジェクト
=======================

クラス "UserDict" は、辞書オブジェクトのラッパとしてはたらきます。この
クラスの必要性は、 "dict" から直接的にサブクラス化できる能力に部分的に
取って代わられました; しかし、根底の辞書に属性としてアクセスできるので
、このクラスを使った方が簡単になることもあります。

class collections.UserDict([initialdata])

   辞書をシミュレートするクラスです。インスタンスの内容は通常の辞書に
   保存され、 "UserDict" インスタンスの "data" 属性を通してアクセスで
   きます。 *initialdata* が与えられれば、 "data" はその内容で初期化さ
   れます。他の目的のために使えるように、 *initialdata* への参照が保存
   されないことに注意してください。

   マッピングのメソッドと演算をサポートするのに加え、 "UserDict" イン
   スタンスは以下の属性を提供します:

   data

      "UserDict" クラスの内容を保存するために使われる実際の辞書です。


"UserList" オブジェクト
=======================

このクラスはリストオブジェクトのラッパとしてはたらきます。これは独自の
リスト風クラスの基底クラスとして便利で、既存のメソッドをオーバーライド
したり新しいメソッドを加えたりできます。こうして、リストに新しい振る舞
いを加えられます。

このクラスの必要性は、 "list" から直接的にサブクラス化できる能力に部分
的に取って代わられました; しかし、根底のリストに属性としてアクセスでき
るので、このクラスを使った方が簡単になることもあります。

class collections.UserList([list])

   リストをシミュレートするクラスです。インスタンスの内容は通常のリス
   トに保存され、 "UserList" インスタンスの "data" 属性を通してアクセ
   スできます。インスタンスの内容は最初に *list* のコピーに設定されま
   すが、デフォルトでは空リスト "[]" です。 *list* は何らかのイテラブ
   ル、例えば通常の Python リストや "UserList" オブジェクト、です。

   ミュータブルシーケンスのメソッドと演算をサポートするのに加え、
   "UserList" インスタンスは以下の属性を提供します:

   data

      "UserList" クラスの内容を保存するために使われる実際の "list" オ
      ブジェクトです。

**サブクラス化の要件:** "UserList" のサブクラスは引数なしか、あるいは
一つの引数のどちらかとともに呼び出せるコンストラクタを提供することが期
待されています。新しいシーケンスを返すリスト演算は現在の実装クラスのイ
ンスタンスを作成しようとします。そのために、データ元として使われるシー
ケンスオブジェクトである一つのパラメータとともにコンストラクタを呼び出
せると想定しています。

派生クラスがこの要求に従いたくないならば、このクラスがサポートしている
すべての特殊メソッドはオーバーライドされる必要があります。その場合に提
供される必要のあるメソッドについての情報は、ソースを参考にしてください
。


"UserString" オブジェクト
=========================

クラス "UserString" は、文字列オブジェクトのラッパとしてはたらきます。
このクラスの必要性は、 "str" から直接的にサブクラス化できる能力に部分
的に取って代わられました; しかし、根底の文字列に属性としてアクセスでき
るので、このクラスを使った方が簡単になることもあります。

class collections.UserString(seq)

   文字列オブジェクトをシミュレートするクラスです。 インスタンスの内容
   は通常の文字列に保存され、 "UserString" インスタンスの "data" 属性
   を通してアクセスできます。 インスタンスの内容には最初に *seq* のコ
   ピーが設定されます。 *seq* 引数は、組み込みの "str()" 関数で文字列
   に変換できる任意のオブジェクトです。

   文字列のメソッドと演算をサポートするのに加え、 "UserString" インス
   タンスは次の属性を提供します:

   data

      "UserString" クラスの内容を保存するために使われる実際の "str" オ
      ブジェクトです。

   バージョン 3.5 で変更: 新たなメソッド "__getnewargs__", "__rmod__",
   "casefold", "format_map", "isprintable", "maketrans"。
