dictionary initialization

Bengt Richter bokr at oz.net
Thu Nov 25 14:28:00 EST 2004


On Thu, 25 Nov 2004 18:38:17 +0000 (UTC), wgshi at namao.cs.ualberta.ca (Weiguang Shi) wrote:

>Hi,
>
>With awk, I can do something like
>    $ echo 'hello' |awk '{a[$1]++}END{for(i in a)print i, a[i]}'
>
>That is, a['hello'] was not there but allocated and initialized to
>zero upon reference.
>
>With Python, I got
>    >>> b={}
>    >>> b[1] = b[1] +1
>    Traceback (most recent call last):
>      File "<stdin>", line 1, in ?
>    KeyError: 1
>
>That is, I have to initialize b[1] explicitly in the first place.
>
>Personally, I think
>
>    a[i]++
>
>in awk is much more elegant than
>
>    if i in a: a[i] += 1
>    else: a[i] = 1
>
>I wonder how the latter is justified in Python.
>
You wrote it, so you have to "justify" it ;-)

While I agree that ++ and -- are handy abbreviations, and creating a key by default
makes for concise notation,  a[i]++ means you have to make some narrow assumptions -- i.e.,
that you want to create a zero integer start value. You can certainly make a dict subclass
that behaves that way if you want it:

 >>> class D(dict):
 ...      def __getitem__(self, i):
 ...          if i not in self: self[i] = 0
 ...          return dict.__getitem__(self, i)
 ...
 >>> dink = D()
 >>> dink
 {}
 >>> dink['a'] +=1
 >>> dink
 {'a': 1}
 >>> dink['a'] +=1
 >>> dink
 {'a': 2}
 >>> dink['b']
 0
 >>> dink['b']
 0
 >>> dink
 {'a': 2, 'b': 0}


Otherwise the usual ways are along the lines of

 >>> d = {}
 >>> d.setdefault('hello',[0])[0] += 1
 >>> d
 {'hello': [1]}
 >>> d.setdefault('hello',[0])[0] += 1
 >>> d
 {'hello': [2]}

Or
 >>> d['hi'] = d.get('hi', 0) + 1
 >>> d
 {'hi': 1, 'hello': [2]}
 >>> d['hi'] = d.get('hi', 0) + 1
 >>> d
 {'hi': 2, 'hello': [2]}
 >>> d['hi'] = d.get('hi', 0) + 1
 >>> d
 {'hi': 3, 'hello': [2]}

Or
 >>> for x in xrange(3):
 ...     try: d['yo'] += 1
 ...     except KeyError: d['yo'] = 1
 ...     print d
 ...
 {'hi': 3, 'hello': [2], 'yo': 1}
 {'hi': 3, 'hello': [2], 'yo': 2}
 {'hi': 3, 'hello': [2], 'yo': 3}

Regards,
Bengt Richter



More information about the Python-list mailing list