web-dev-qa-db-fra.com

python defaultdict: 0 vs int et [] vs list

Y a-t-il une différence entre passer int et lambda: 0 comme arguments? Ou entre list et lambda: []?

On dirait qu'ils font la même chose:

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

mais y a-t-il des cas où ils auront un comportement différent, ou s'agit-il simplement d'une différence de notation?

36
beardc

Tout ce que defaultdict requiert est un objet appelable qui retournera ce qui devrait être utilisé comme valeur par défaut lorsqu'il est appelé sans paramètres.

Si vous deviez appeler le constructeur int, il retournerait 0 et si vous deviez appeler lambda: 0, il renverrait 0. Même chose avec les listes. La seule différence ici est que le constructeur utilisera toujours sa logique pour créer l'objet. Un lambda, vous pouvez ajouter une logique supplémentaire si vous choisissez de le faire.

par exemple.,

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