Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Dictionary get method to return empty list by default returns None instead

In Python I would like to build up an dictionary of arrays using the dictionary get method to by default supply an empty list to then populate with information e.g.:

dct = {}
for i in range(0, 10):
    for j in range(0, 100):
        dct[i] = dct.get(i, []).append(j)

However when I try the above code I get no exceptions but my list ends up like the following:

AttributeError: 'NoneType' object has no attribute 'append'

Lists have an append method, so I simplified my test to the following:

dct = {}
for i in range(0, 10):
    dct[i] = dct.get(i, []).append(i)

And the output was the following:

{0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None, 7: None, 8: None, 9: None}

So my question is why is dct.get(i, []) returning None by default and not []? Doing dct.get(i, list()) has the same problem, so I am a bit stumped.

like image 407
Danielb Avatar asked Apr 24 '11 17:04

Danielb


2 Answers

To solve this you should use Python's defaultdict. The first time you use a key that doesn't exist, the argument to the defaultdict constructor is used to create a value (in this case, a list).

http://docs.python.org/library/collections.html#defaultdict-examples

from collections import defaultdict   d = defaultdict(list) for i in range( 0, 10 ):     for j in range( 0, 100 ):         d[i].append( j ) 

You can also pass a function as the argument to defaultdict if you want to do anything more elaborate.

like image 89
Steve Mayne Avatar answered Nov 14 '22 02:11

Steve Mayne


It's not dict.get( i, [] ) that's returning None, it's append. You probably want to use dict.setdefault(i, []).append(j) or just use a defaultdict in the first place.

Here's how you would do it:

d = {}
for i in range( 0, 10 ):
    for j in range( 0, 100 ):
        d.setdefault( i, [] ).append( j )

Note that I changed dict to d because dict already means something in Python (you're redefining it) and I removed the superfluous dict[i] = that was causing the error message.

like image 23
Gabe Avatar answered Nov 14 '22 01:11

Gabe