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