Search code examples
pythondictionarycollectionsdefaultdict

from collections import defaultdict


why is it when I do not set default value of defaultdict to be zero (int), my below program does not give me results:

>>> doc
'A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart. I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine. I am so happy'
>>> some = defaultdict()
>>> for i in doc.split():
...  some[i] = some[i]+1
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyError: 'A'
>>> some
defaultdict(None, {})
>>> i
'A'

yet it works with a default value

>>> some = defaultdict(int)
>>> for i in doc.split():
...  some[i] = some[i]+1
...
>>> some
defaultdict(<class 'int'>, {'A': 1, 'wonderful': 1, 'serenity': 1, 'has': 1, 'taken': 1, 'possession': 1, 'of': 4, 'my': 2, 'entire': 1, 'soul,': 1, 'like': 2, 'these': 1, 'sweet': 1, 'mornings': 1, 'spring': 1, 'which': 2, 'I': 3, 'enjoy': 1, 'with': 1, 'whole': 1, 'heart.': 1, 'am': 2, 'alone,': 1, 'and': 1, 'feel': 1, 'the': 2, 'charm': 1, 'existence': 1, 'in': 1, 'this': 1, 'spot,': 1, 'was': 1, 'created': 1, 'for': 1, 'bliss': 1, 'souls': 1, 'mine.': 1, 'so': 1, 'happy': 1})
>>>

Could you tell why does it work like thus?


Solution

  • As the documentation says:

    The first argument provides the initial value for the default_factory attribute; it defaults to None. All remaining arguments are treated the same as if they were passed to the dict constructor, including keyword arguments.

    Therefore, if you just write defaultdict without passing any value to the constructor, the default value is set to None See the output:

    some = defaultdict()
    print(some)    # defaultdict(None, {}) 
    

    And when the value is set to None, you can not execute: some[i] = some[i]+1.
    Thus, you have to set the default value to int explicitly: some = defaultdict(int)