Подтвердить что ты не робот

Python defaultdict: 0 против int и [] vs list

Есть ли разница между передачей int и lambda: 0 в качестве аргументов? Или между list и lambda: []?

Похоже, они делают то же самое:

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

но есть ли случаи, когда у них будет другое поведение, или это просто отличительная разница?

4b9b3361

Ответ 1

Все, что требуется 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)