2015-11-22 3 views
3

Что именно делает TYPE lambda при использовании с defaultdict? У меня есть этот пример и отлично работает даже для int, list & lambda в качестве аргумента:Разница между defaultdict (lambda: None) и defaultdict (int)

d = defaultdict(int) 
d['one'] = lambda x:x*x 
d['one'](2) 
4 

d = defaultdict(list) 
d['one'] = lambda x:x*x 
d['one'](2) 
4 

d = defaultdict(lambda: None) 
d['one'] = lambda x:x*x 
d['one'](2) 
4 

У меня есть один и тот же результат каждый раз. Итак, какова основная причина для инициализации с помощью lambda «default (lambda: None)»? Looks defaultdict словарь не заботится о том, в каком типе аргумента передается.

+0

Вы можете получить ответ на него по следующей ссылке https://stackoverflow.com/a/49184504/7187965 –

ответ

2

Вы не используете заводскую настройку по умолчанию. Вы не увидите разницы, если все, что вы делаете, это назначить клавишам, а не пытаться и получить ключ, которого нет в словаре.

Заводская установка по умолчанию (первый аргумент defaultdict()) - не декларация типа. Это вместо называется всякий раз, когда вы пытаетесь получить доступ ключа, который отсутствует в словаре еще:

>>> from collections import defaultdict 
>>> def demo_factory(): 
...  print('Called the factory for a missing key') 
...  return 'Default value' 
... 
>>> d = defaultdict(demo_factory) 
>>> list(d) # list the keys 
[] 
>>> d['foo'] 
Called the factory for a missing key 
'Default value' 
>>> list(d) 
['foo'] 
>>> d['foo'] 
'Default value' 
>>> d['bar'] = 'spam' # assignment is not the same thing 
>>> list(d) 
['foo', 'bar'] 
>>> d['bar'] 
'spam'  

Только первый раз, когда я попытался получить доступ к ключевому 'foo' был завод призван производить значение по умолчанию , который затем сохраняется в словаре для будущего доступа.

Итак, для каждого из ваших разных примеров, что меняется между ними, будет выбрано значение по умолчанию для каждого. Вы никогда не получаете доступ к этой функции, потому что вы напрямую назначили ключ 'one'.

Если бы вы получили доступ к несуществующему ключу, вы бы создали целое число со значением 0, пустой список или None, соответственно.

3

Ваш пример имеет смысл только тогда, когда доступ к разделам, которые явно не добавляется в словарь:

>>> d = defaultdict(int) 
>>> d['one'] 
0 
>>> d = defaultdict(list) 
>>> d['one'] 
[] 
>>> d = defaultdict(lambda: None) 
>>> d['one'] is None 
True 

Как вы можете видеть, используя Dict по умолчанию даст каждый ключ вы пытаетесь получить доступ значения по умолчанию. Это значение по умолчанию принимается вызовом функции, которую вы передаете конструктору. Таким образом, передача int установит int() в качестве значения по умолчанию (которое равно 0); передача list установит list() как значение по умолчанию (которое является пустым списком []); и прохождение lambda: None установит (lambda: None)() в качестве значения по умолчанию (которое равно None).

Это то, что делает словарь по умолчанию. Ничего больше.

Идея состоит в том, что таким образом вы можете настроить параметры по умолчанию, которые вам не нужны, чтобы вручную настроить первый раз, когда вы хотите получить доступ к ключу. Так, например, что-то вроде этого:

d = {} 
for item in some_source_for_items: 
    if item['key'] not in d: 
     d[item['key']] = [] 

    d[item['key']].append(item) 

который просто устанавливает новый пустой список для каждого словаря элемента при доступе, может быть сведено к следующим образом:

d = defaultdict(list) 
for item in some_source_for_items: 
    d[item['key']].append(item) 

И defaultdict сделает обязательно правильно инициализируйте список.