web-dev-qa-db-ja.com

python defaultdict:0 vs. intおよび[] vsリスト

intlambda: 0を引数として渡すことに違いはありますか?またはlistlambda: []の間?

彼らは同じことをしているようです:

from collections import defaultdict
dint1 = defaultdict(lambda: 0)
dint2 = defaultdict(int)
dlist1 = defaultdict(lambda: [])
dlist2 = defaultdict(list)

for ch in 'abracadabra':
    dint1[ch] += 1
    dint2[ch] += 1
    dlist1[ch].append(1)
    dlist2[ch].append(1)

print dint1.items()
print dint2.items()
print dlist1.items()
print dlist2.items()
## -- Output: --
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
[('a', [1, 1, 1, 1, 1]), ('r', [1, 1]), ('b', [1, 1]), ('c', [1]), ('d', [1])]
[('a', [1, 1, 1, 1, 1]), ('r', [1, 1]), ('b', [1, 1]), ('c', [1]), ('d', [1])]

しかし、それらが異なる動作をするケースはありますか、それとも単なる表記上の違いですか?

36
beardc

defaultdictに必要なのは、パラメーターなしで呼び出されたときにデフォルト値として使用されるものを返す呼び出し可能なオブジェクトだけです。

intコンストラクタを呼び出すと、0が返され、lambda: 0を呼び出すと、0が返されます。リストと同じです。ここでの唯一の違いは、コンストラクターは常にそのロジックを使用してオブジェクトを作成することです。ラムダ、そうすることを選択した場合は、ロジックを追加できます。

例えば。、

# alternating between `0` and `[]`
from itertools import count
factory = lambda c=count(): 0 if next(c) % 2 else []
superdict = defaultdict(factory)
42
Jeff Mercado