Python で Defaultdict の Defaultdict を作成する

Olorunfemi Akinlua 2023年6月21日
Python で Defaultdict の Defaultdict を作成する

Python には、dict、list、set、tuple などのコンテナーが組み込まれており、これらには汎用的なイデオロギーがあります。 これらの汎用コンテナーを拡張または改善するために、Python は、Python コレクションと呼ばれる特殊なコンテナー データ型を導入するモジュールを提供します。

そのような特殊なコンテナー データ型の 1つに defaultdict があります。これは、既定の Python 辞書 (dict) の優れた代替 (およびサブクラス) です。 defaultdict を使用すると、(KeyError 例外やメッセージではなく) 欠損値を提供する factory 関数を提供できます。

そのため、キーがディクショナリ内に存在しない場合、factory 関数が呼び出され、KeyError 例外を発生させるのではなく、値を返します。

defaultdict を使用するのは比較的簡単かもしれませんが、defaultdictdefaultdict を使用すると混乱する可能性があります。 この記事では、エラーを発生させずに defaultdictdefaultdict を作成する方法と、その固有の操作がどのように行われるかについて説明します。

Python で lambda を使用して Defaultdict の Defaultdict を作成する

Python コレクションと本質的に defaultdict を利用するには、Python 式を使用して collection モジュールをインポートできます。

from collections import defaultdict

defaultdictdict クラスのサブクラスであり、次の Python 式でチェックできることに注意してください。

issubclass(defaultdict, dict)

出力:

True

dict では、存在しないキーがディクショナリに渡されると、None に設定された default_factory 属性を保持する __missing__ メソッドがトリガーされるため、KeyError 例外が発生します。 ただし、default_dict では、存在しないキーがディクショナリに渡されると、__missing__ メソッドの default_factory 属性がトリガーされます。この属性は、デフォルト値を返す factory を保持します。

たとえば、存在しないキーが渡されたときに空のリストを返す factory 関数 list を保持する defaultdict ディクショナリを使用できます。

from collections import defaultdict

ddict = defaultdict(list)
print(ddict["one"])

出力:

[]

ddict はキー one を持っていませんが、factory 関数が渡されているため、空のリストの値を返します。 そのような式の後にキーを作成することさえあります。

from collections import defaultdict

ddict = defaultdict(list)
print(ddict["one"])
print(ddict["two"].append(1))

print(ddict)

出力:

[]
defaultdict(<class 'list'>, {'one': [], 'two': [1]})

したがって、ddict["one"] および ddict["two"].append(1) ステートメントの後に、それぞれのキーと対応する値が list 関数に基づいて作成されます。 2 番目の Python ステートメントでは、default_factory 属性関数に基づいて空のリストを作成し、それに値 1 を追加します。

defaultdict データ型内の値の一般的なグループ化は、dict データ型とは異なる方法で処理できます。

sentence = "the man loves oranges, but also cares a great deal about apples"

letterStore = dict()

for i in sentence:
    if k not in letterStore:
        letterStore[i] = 1
        continue
    letterStore[i] += 1

print(letterStore.items())

出力:

dict_items([('t', 4), ('h', 1), ('e', 7), (' ', 11), ('m', 1), ('a', 9), ('n', 2), ('l', 4), ('o', 4), ('v', 1), ('s', 5), ('r', 3), ('g', 2), (',', 1), ('b', 2), ('u', 2), ('c', 1), ('d', 1), ('p', 2)])

上記の文字のグループ化は、代わりに defaultdict を使用して簡単に行うことができます。 最初の番号付けを作成するために、文字がすでに letterStore バインディングにあるかどうかをチェックするコード ブロックを使用する代わりに、defaultdict を使用して、factory 関数である int を使用してこれを実現できます。

from collections import defaultdict

sentence = "the man loves oranges, but also cares a great deal about apples"

letterStore = defaultdict(int)

for i in sentence:
    letterStore[i] += 1

print(letterStore.items())

出力:

dict_items([('t', 4), ('h', 1), ('e', 7), (' ', 11), ('m', 1), ('a', 9), ('n', 2), ('l', 4), ('o', 4), ('v', 1), ('s', 5), ('r', 3), ('g', 2), (',', 1), ('b', 2), ('u', 2), ('c', 1), ('d', 1), ('p', 2)])

これで、キーが存在しない場合、__missing__ メソッドが呼び出されることがわかります。 値を返す関数を保持する属性 default_factory もトリガーされます。

しかし、defaultdictdefaultdict を作成することはできますか? はい、でもどうすればできますか? defaultdict を別の defaultdict に渡すと、エラーが発生するためです。

from collections import defaultdict

d = defaultdict(defaultdict(int))
print(d)

出力:

Traceback (most recent call last):
  File "c:\Users\USER\Desktop\JS\test.py", line 3, in <module>
    d = defaultdict(defaultdict(int))
TypeError: first argument must be callable or None

コードを実行すると TypeError がスローされます。これは d = defaultdict(defaultdict(int)) という行が原因で発生し、最初の引数は callable または None でなければなりません と書かれています。

この情報から、callable (関数) または None (default_factory が保持するデフォルト値) を渡さなかったと推測できます。これは、defaultdict(int) が callable ではないためです。 ただし、これは'collections.defaultdict'です。

したがって、呼び出し可能オブジェクトを渡す方法を見つける必要があります。ここで lambda が入ります。

lambda を使用すると、呼び出すことができる無名関数 (callable) を作成できます。 したがって、上位レベルの defaultdict には、存在しないキーを渡すと呼び出される defaultdict(int) を指す lambda 関数を渡すことができます。

lambda 関数は、内部の defaultdict 内で factory 関数を呼び出し、キー値として設定されるその値を返します。

from collections import defaultdict

d = defaultdict(lambda: defaultdict(int))
print(d)

出力:

defaultdict(<function <lambda> at 0x000001F6B9383E20>, {})

正常に動作することを示すために、平方表記を使用してトップレベルの defaultdict と内部レベルの defaultdict にアクセスし、それぞれ lambda 関数と int 関数に渡されるデフォルト値を確認できます。 .

print(d[0])
print(d[0][0])

出力:

defaultdict(<class 'int'>, {})
0
Olorunfemi Akinlua avatar Olorunfemi Akinlua avatar

Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.

LinkedIn

関連記事 - Python Dictionary