Thanks Chris,<br>  yes it's becoming clearer now.<br>And defaultdict looks nice - unfortunately I'm stuck to python 2.4 as I'm using Plone.<br><br>Thanks again,<br>Daniel<br><br><br><div class="gmail_quote">2009/11/11 Chris Rebert <span dir="ltr"><<a href="mailto:clp2@rebertia.com">clp2@rebertia.com</a>></span><br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div><div></div><div class="h5">On Wed, Nov 11, 2009 at 4:16 AM, Daniel Jowett <<a href="mailto:daniel.jowett@gmail.com">daniel.jowett@gmail.com</a>> wrote:<br>

> Greetings,<br>
><br>
> I'm trying to categorize items in a list, by copying them into a<br>
> dictionary...<br>
> A simple example with strings doesn't seem to work how I'd expect:<br>
><br>
>>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']<br>
>>>> d = {}<br>
>>>> d = d.fromkeys(basket, [])<br>
>>>> d<br>
> {'orange': [], 'pear': [], 'apple': [], 'banana': []}<br>
>>>> for fruit in basket:<br>
> ...     d[fruit].append(fruit)<br>
> ...<br>
><br>
> No if I print d I'd EXPECT....<br>
>>>> d<br>
> {'orange': ['orange', 'orange'], 'pear': ['pear'], 'apple': ['apple',<br>
> 'apple'], 'banana': ['banana']}<br>
><br>
> But what I GET is....<br>
>>>> d<br>
> {'orange': ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'], 'pear':<br>
> ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'], 'apple': ['apple',<br>
> 'orange', 'apple', 'pear', 'orange', 'banana'], 'banana': ['apple',<br>
> 'orange', 'apple', 'pear', 'orange', 'banana']}<br>
>>>><br>
><br>
> From what I can work out, there is only ONE list that is referenced from the<br>
> dictionary 4 times. Which would be because the same empty list is assigned<br>
> to every key in the dictionary by the "fromkeys" line. But that seems<br>
> seriously counter-intuitive to me...<br>
<br>
</div></div>Python doesn't do any extra copying in most places unless you<br>
/explicitly/ do so yourself or ask it to; so yes, in this case, Python<br>
just copies references to the same object and does not copy the object<br>
itself.<br>
<br>
You'd probably be better off using a defaultdict in your particular usecase:<br>
<a href="http://docs.python.org/library/collections.html#collections.defaultdict" target="_blank">http://docs.python.org/library/collections.html#collections.defaultdict</a><br>
<br>
Or and so you avoid running into it, default argument values aren't<br>
copied either:<br>
In [2]: def foo(z, a=[]):<br>
   ...:         a.append(z)<br>
   ...:     return a<br>
   ...:<br>
<br>
In [3]: foo(1)<br>
Out[3]: [1]<br>
<br>
In [4]: foo(2)<br>
Out[4]: [1, 2]<br>
<br>
In [5]: foo(2)<br>
Out[5]: [1, 2, 2]<br>
<br>
In [6]: foo(3)<br>
Out[6]: [1, 2, 2, 3]<br>
<br>
In [7]: foo(4,[])<br>
Out[7]: [4]<br>
<br>
In [8]: foo(5)<br>
Out[8]: [1, 2, 2, 3, 5]<br>
<br>
<br>
Cheers,<br>
Chris<br>
<font color="#888888">--<br>
<a href="http://blog.rebertia.com" target="_blank">http://blog.rebertia.com</a><br>
</font></blockquote></div><br>