Basic list/dictionary question

Chris Rebert clp2 at rebertia.com
Wed Nov 11 13:58:55 CET 2009


On Wed, Nov 11, 2009 at 4:16 AM, Daniel Jowett <daniel.jowett at gmail.com> wrote:
> Greetings,
>
> I'm trying to categorize items in a list, by copying them into a
> dictionary...
> A simple example with strings doesn't seem to work how I'd expect:
>
>>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>>> d = {}
>>>> d = d.fromkeys(basket, [])
>>>> d
> {'orange': [], 'pear': [], 'apple': [], 'banana': []}
>>>> for fruit in basket:
> ...     d[fruit].append(fruit)
> ...
>
> No if I print d I'd EXPECT....
>>>> d
> {'orange': ['orange', 'orange'], 'pear': ['pear'], 'apple': ['apple',
> 'apple'], 'banana': ['banana']}
>
> But what I GET is....
>>>> d
> {'orange': ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'], 'pear':
> ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'], 'apple': ['apple',
> 'orange', 'apple', 'pear', 'orange', 'banana'], 'banana': ['apple',
> 'orange', 'apple', 'pear', 'orange', 'banana']}
>>>>
>
> From what I can work out, there is only ONE list that is referenced from the
> dictionary 4 times. Which would be because the same empty list is assigned
> to every key in the dictionary by the "fromkeys" line. But that seems
> seriously counter-intuitive to me...

Python doesn't do any extra copying in most places unless you
/explicitly/ do so yourself or ask it to; so yes, in this case, Python
just copies references to the same object and does not copy the object
itself.

You'd probably be better off using a defaultdict in your particular usecase:
http://docs.python.org/library/collections.html#collections.defaultdict

Or and so you avoid running into it, default argument values aren't
copied either:
In [2]: def foo(z, a=[]):
   ...:         a.append(z)
   ...:     return a
   ...:

In [3]: foo(1)
Out[3]: [1]

In [4]: foo(2)
Out[4]: [1, 2]

In [5]: foo(2)
Out[5]: [1, 2, 2]

In [6]: foo(3)
Out[6]: [1, 2, 2, 3]

In [7]: foo(4,[])
Out[7]: [4]

In [8]: foo(5)
Out[8]: [1, 2, 2, 3, 5]


Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list