On Wed, Nov 11, 2009 at 4:16 AM, Daniel Jowett <daniel.jow...@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 -- http://mail.python.org/mailman/listinfo/python-list