Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Dictionary of lists strange behaviour

Reply
Thread Tools

Dictionary of lists strange behaviour

 
 
Ciccio
Guest
Posts: n/a
 
      11-09-2010
Hi all,

hope you can help me understanding why the following happens:

In [213]: g = {'a': ['a1','a2'], 'b':['b1','b2']}
In [214]: rg = dict.fromkeys(g.keys(),[])
In [215]: rg
Out[215]: {'a': [], 'b': []}
In [216]: rg['a'].append('x')
In [217]: rg
Out[217]: {'a': ['x'], 'b': ['x']}

What I meant was appending 'x' to the list pointed by the key 'a' in the
dictionary 'rg'. Why rg['b'] is written too?

Thanks.
 
Reply With Quote
 
 
 
 
Matteo Landi
Guest
Posts: n/a
 
      11-09-2010
On Tue, Nov 9, 2010 at 3:14 PM, Ciccio <> wrote:
> Hi all,
>
> hope you can help me understanding why the following happens:
>
> In [213]: g = {'a': ['a1','a2'], 'b':['b1','b2']}
> In [214]: rg = dict.fromkeys(g.keys(),[])


The argument you pass which is used to fill the values of the new
dict, is created once; this means that the empty list is shared
between all the keys of the dict.
I think you need to create the new dict by hand.

Regards,
Matteo

> In [215]: rg
> Out[215]: {'a': [], 'b': []}
> In [216]: rg['a'].append('x')
> In [217]: rg
> Out[217]: {'a': ['x'], 'b': ['x']}
>
> What I meant was appending 'x' to the list pointed by the key 'a' in the
> dictionary 'rg'. Why rg['b'] is written too?
>
> Thanks.
> --
> http://mail.python.org/mailman/listinfo/python-list
>




--
Matteo Landi
http://www.matteolandi.net/
 
Reply With Quote
 
 
 
 
Jean-Michel Pichavant
Guest
Posts: n/a
 
      11-09-2010
Ciccio wrote:
> Hi all,
>
> hope you can help me understanding why the following happens:
>
> In [213]: g = {'a': ['a1','a2'], 'b':['b1','b2']}
> In [214]: rg = dict.fromkeys(g.keys(),[])
> In [215]: rg
> Out[215]: {'a': [], 'b': []}
> In [216]: rg['a'].append('x')
> In [217]: rg
> Out[217]: {'a': ['x'], 'b': ['x']}
>
> What I meant was appending 'x' to the list pointed by the key 'a' in
> the dictionary 'rg'. Why rg['b'] is written too?
>
> Thanks.


rg = dict.fromkeys(g.keys(),[])

you are intialising the content with the same object [].

write instead

for key in g:
rg[key] = [] # python create a new list everytime it hits this line

For the same reason you never assign an empty list to default parameters
value:

In [37]: def a(p=[]):
....: return p
....:

In [38]: a1 = a()

In [39]: a2 = a()

In [40]: id(a1) ; id(a2)
Out[40]: 161119884
Out[40]: 161119884

Jean-Michel
 
Reply With Quote
 
Dave Angel
Guest
Posts: n/a
 
      11-09-2010


On 2:59 PM, Ciccio wrote:
> Hi all,
>
> hope you can help me understanding why the following happens:
>
> In [213]: g = {'a': ['a1','a2'], 'b':['b1','b2']}
> In [214]: rg = dict.fromkeys(g.keys(),[])
> In [215]: rg
> Out[215]: {'a': [], 'b': []}
> In [216]: rg['a'].append('x')
> In [217]: rg
> Out[217]: {'a': ['x'], 'b': ['x']}
>
> What I meant was appending 'x' to the list pointed by the key 'a' in
> the dictionary 'rg'. Why rg['b'] is written too?
>
> Thanks.
>

The second argument to the fromkeys() method is an empty list object.
So that object is the value for *both* the new dictionary items. It
does not make a new object each time, it uses the same one.

You can check this for yourself, by doing
id(rg["a"]) and id(rg["b"])

I'd do something like :

rg = {}
for key in g.keys():
rg[key] = []

DaveA
 
Reply With Quote
 
Terry Reedy
Guest
Posts: n/a
 
      11-09-2010
On 11/9/2010 9:14 AM, Ciccio wrote:
> Hi all,
>
> hope you can help me understanding why the following happens:
>
> In [213]: g = {'a': ['a1','a2'], 'b':['b1','b2']}
> In [214]: rg = dict.fromkeys(g.keys(),[])


If you rewrite this as

bl = []
rg = dict.fromkeys(g.keys(),bl)

is the answer any more obvious?


> In [215]: rg
> Out[215]: {'a': [], 'b': []}
> In [216]: rg['a'].append('x')
> In [217]: rg
> Out[217]: {'a': ['x'], 'b': ['x']}
>
> What I meant was appending 'x' to the list pointed by the key 'a' in the
> dictionary 'rg'. Why rg['b'] is written too?



--
Terry Jan Reedy

 
Reply With Quote
 
Ciccio
Guest
Posts: n/a
 
      11-09-2010
Il 09/11/2010 16:47, Terry Reedy ha scritto:
> On 11/9/2010 9:14 AM, Ciccio wrote:
>> Hi all,
>>
>> hope you can help me understanding why the following happens:
>>
>> In [213]: g = {'a': ['a1','a2'], 'b':['b1','b2']}
>> In [214]: rg = dict.fromkeys(g.keys(),[])

>
> If you rewrite this as
>
> bl = []
> rg = dict.fromkeys(g.keys(),bl)
>
> is the answer any more obvious?


It isn't since I erroneously assumed that a clone of the object would be
made in both cases.

Thanks for your help
 
Reply With Quote
 
Ciccio
Guest
Posts: n/a
 
      11-09-2010
Thank you all, this was timely and helpful.
francesco
 
Reply With Quote
 
Terry Reedy
Guest
Posts: n/a
 
      11-09-2010
On 11/9/2010 12:19 PM, Ciccio wrote:
> Il 09/11/2010 16:47, Terry Reedy ha scritto:
>> On 11/9/2010 9:14 AM, Ciccio wrote:
>>> Hi all,
>>>
>>> hope you can help me understanding why the following happens:
>>>
>>> In [213]: g = {'a': ['a1','a2'], 'b':['b1','b2']}
>>> In [214]: rg = dict.fromkeys(g.keys(),[])

>>
>> If you rewrite this as
>>
>> bl = []
>> rg = dict.fromkeys(g.keys(),bl)
>>
>> is the answer any more obvious?

>
> It isn't since I erroneously assumed that a clone of the object would be
> made in both cases.


I can see how you might think that, especially if you have experience
with other languages where that would be usual. In Python, the general
policy is to not copy objects unless explicitly requested. None, False,
and True cannot be copied. There is essentially never a reason to copy a
number or string or tuple.

I believe dict.fromkeys is more usually given None or 0 or '' as value
initializer. List *is* useful as an initializer for
collecitons.defaultdicts.

--
Terry Jan Reedy

 
Reply With Quote
 
John Posner
Guest
Posts: n/a
 
      11-09-2010
On 11/9/2010 1:43 PM, Terry Reedy wrote:
> ... List *is* useful as an initializer for
> collecitons.defaultdicts.


And it was useful when several members of this forum helped me to
develop a prime-number generator.

See http://www.mail-archive.com/python-l...msg288128.html.

(I meant to post this to the "functions, list, default parameters"
thread, but never got a round tuit.)

-John





 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Performance ordered dictionary vs normal dictionary Navkirat Singh Python 6 07-29-2010 10:18 AM
Re: Performance ordered dictionary vs normal dictionary Chris Rebert Python 0 07-29-2010 06:11 AM
creating a dictionary from a dictionary with regex james_027 Python 1 08-22-2007 07:39 AM
List of lists of lists of lists... =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==?= Python 5 05-15-2006 11:47 AM
[DICTIONARY] - Copy dictionary entries to attributes Ilias Lazaridis Python 6 02-21-2006 11:27 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57