Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.python

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 04-30-2009, 05:45 PM
Sneaky Wombat
Guest
 
Posts: n/a
Default using zip() and dictionaries

I'm really confused by what is happening here. If I use zip(), I
can't update individual dictionary elements like I usually do. It
updates all of the dictionary elements. It's hard to explain, so here
is some output from an interactive session:

In [52]: header=['a','b','c','d']
In [53]: columnMap={}
In [54]: for (k,v) in zip(header,[[]]*len(header)):
....: #print "%s,%s"%(k,v)
....: columnMap[k] = v
....:
In [55]: columnMap
Out[55]: {'a': [], 'b': [], 'c': [], 'd': []}
In [56]: columnMap['a'].append('something')
In [57]: columnMap
Out[57]:
{'a': ['something'],
'b': ['something'],
'c': ['something'],
'd': ['something']}

Why does ['something'] get attached to all columnMap elements instead
of just element 'a'?


In [58]: columnMap={'a': [], 'b': [], 'c': [], 'd': []}
In [59]: columnMap['a'].append('something')
In [60]: columnMap
Out[60]: {'a': ['something'], 'b': [], 'c': [], 'd': []}

creating the dictionary without using zip, it works as normal.
Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 04-30-2009, 06:00 PM
Sneaky Wombat
Guest
 
Posts: n/a
Default Re: using zip() and dictionaries

quick update,

#change this line:
for (k,v) in zip(header,[[]]*len(header)):
#to this line:
for (k,v) in zip(header,[[],[],[],[]]):

and it works as expected. Something about the [[]]*len(header) is
causing the weird behavior. I'm probably using it wrong, but if
anyone can explain why that would happen, i'd appreciate it. My guess
is that it's iterating through the the whole dictionary because of the
value on the right in zip().


On Apr 30, 12:45*pm, Sneaky Wombat <> wrote:
> I'm really confused by what is happening here. *If I use zip(), I
> can't update individual dictionary elements like I usually do. *It
> updates all of the dictionary elements. *It's hard to explain, so here
> is some output from an interactive session:
>
> In [52]: header=['a','b','c','d']
> In [53]: columnMap={}
> In [54]: for (k,v) in zip(header,[[]]*len(header)):
> * *....: * * #print "%s,%s"%(k,v)
> * *....: * * columnMap[k] = v
> * *....:
> In [55]: columnMap
> Out[55]: {'a': [], 'b': [], 'c': [], 'd': []}
> In [56]: columnMap['a'].append('something')
> In [57]: columnMap
> Out[57]:
> {'a': ['something'],
> *'b': ['something'],
> *'c': ['something'],
> *'d': ['something']}
>
> Why does ['something'] get attached to all columnMap elements instead
> of just element 'a'?
>
> In [58]: columnMap={'a': [], 'b': [], 'c': [], 'd': []}
> In [59]: columnMap['a'].append('something')
> In [60]: columnMap
> Out[60]: {'a': ['something'], 'b': [], 'c': [], 'd': []}
>
> creating the dictionary without using zip, it works as normal.


Reply With Quote
  #3 (permalink)  
Old 04-30-2009, 06:05 PM
Sneaky Wombat
Guest
 
Posts: n/a
Default Re: using zip() and dictionaries

quick update,

#change this line:
for (k,v) in zip(header,[[]]*len(header)):
#to this line:
for (k,v) in zip(header,[[],[],[],[]]):

and it works as expected. Something about the [[]]*len(header) is
causing the weird behavior. I'm probably using it wrong, but if
anyone can explain why that would happen, i'd appreciate it. My guess
is that it's iterating through the the whole dictionary because of the
value on the right in zip().


On Apr 30, 12:45*pm, Sneaky Wombat <> wrote:
> I'm really confused by what is happening here. *If I use zip(), I
> can't update individual dictionary elements like I usually do. *It
> updates all of the dictionary elements. *It's hard to explain, so here
> is some output from an interactive session:
>
> In [52]: header=['a','b','c','d']
> In [53]: columnMap={}
> In [54]: for (k,v) in zip(header,[[]]*len(header)):
> * *....: * * #print "%s,%s"%(k,v)
> * *....: * * columnMap[k] = v
> * *....:
> In [55]: columnMap
> Out[55]: {'a': [], 'b': [], 'c': [], 'd': []}
> In [56]: columnMap['a'].append('something')
> In [57]: columnMap
> Out[57]:
> {'a': ['something'],
> *'b': ['something'],
> *'c': ['something'],
> *'d': ['something']}
>
> Why does ['something'] get attached to all columnMap elements instead
> of just element 'a'?
>
> In [58]: columnMap={'a': [], 'b': [], 'c': [], 'd': []}
> In [59]: columnMap['a'].append('something')
> In [60]: columnMap
> Out[60]: {'a': ['something'], 'b': [], 'c': [], 'd': []}
>
> creating the dictionary without using zip, it works as normal.


Reply With Quote
  #4 (permalink)  
Old 04-30-2009, 06:09 PM
Chris Rebert
Guest
 
Posts: n/a
Default Re: using zip() and dictionaries

> On Apr 30, 12:45Â*pm, Sneaky Wombat <> wrote:
>> I'm really confused by what is happening here. Â*If I use zip(), I
>> can't update individual dictionary elements like I usually do. Â*It
>> updates all of the dictionary elements. Â*It's hard to explain, so here
>> is some output from an interactive session:
>>
>> In [52]: header=['a','b','c','d']
>> In [53]: columnMap={}
>> In [54]: for (k,v) in zip(header,[[]]*len(header)):
>> Â* Â*....: Â* Â* #print "%s,%s"%(k,v)
>> Â* Â*....: Â* Â* columnMap[k] = v
>> Â* Â*....:
>> In [55]: columnMap
>> Out[55]: {'a': [], 'b': [], 'c': [], 'd': []}
>> In [56]: columnMap['a'].append('something')
>> In [57]: columnMap
>> Out[57]:
>> {'a': ['something'],
>> Â*'b': ['something'],
>> Â*'c': ['something'],
>> Â*'d': ['something']}
>>
>> Why does ['something'] get attached to all columnMap elements instead
>> of just element 'a'?
>>
>> In [58]: columnMap={'a': [], 'b': [], 'c': [], 'd': []}
>> In [59]: columnMap['a'].append('something')
>> In [60]: columnMap
>> Out[60]: {'a': ['something'], 'b': [], 'c': [], 'd': []}
>>
>> creating the dictionary without using zip, it works as normal.


On Thu, Apr 30, 2009 at 11:00 AM, Sneaky Wombat <joe.hrbek@gmail.com> wrote:
> quick update,
>
> #change this line:
> for (k,v) in zip(header,[[]]*len(header)):
> #to this line:
> for (k,v) in zip(header,[[],[],[],[]]):
>
> and it works as expected. Something about the [[]]*len(header) is
> causing the weird behavior. I'm probably using it wrong, but if
> anyone can explain why that would happen, i'd appreciate it. My guess
> is that it's iterating through the the whole dictionary because of the
> value on the right in zip().


Read http://www.python.org/doc/faq/progra...mensional-list
Basically, the multiplication doesn't create new sub-lists, it just
copies references to the one original empty sublist.

Cheers,
Chris
--
http://blog.rebertia.com
Reply With Quote
  #5 (permalink)  
Old 04-30-2009, 06:23 PM
Sneaky Wombat
Guest
 
Posts: n/a
Default Re: using zip() and dictionaries

Thanks! That certainly explains it. This works as expected.

columnMap={}
for (k,v) in zip(header,[[] for i in range(len(header))]):
#print "%s,%s"%(k,v)
columnMap[k] = v

columnMap['a'].append('test')


(sorry about the double post, accidental browser refresh)

On Apr 30, 1:09*pm, Chris Rebert <c...@rebertia.com> wrote:
> > On Apr 30, 12:45*pm, Sneaky Wombat <> wrote:
> >> I'm really confused by what is happening here. *If I use zip(), I
> >> can't update individual dictionary elements like I usually do. *It
> >> updates all of the dictionary elements. *It's hard to explain, so here
> >> is some output from an interactive session:

>
> >> In [52]: header=['a','b','c','d']
> >> In [53]: columnMap={}
> >> In [54]: for (k,v) in zip(header,[[]]*len(header)):
> >> * *....: * * #print "%s,%s"%(k,v)
> >> * *....: * * columnMap[k] = v
> >> * *....:
> >> In [55]: columnMap
> >> Out[55]: {'a': [], 'b': [], 'c': [], 'd': []}
> >> In [56]: columnMap['a'].append('something')
> >> In [57]: columnMap
> >> Out[57]:
> >> {'a': ['something'],
> >> *'b': ['something'],
> >> *'c': ['something'],
> >> *'d': ['something']}

>
> >> Why does ['something'] get attached to all columnMap elements instead
> >> of just element 'a'?

>
> >> In [58]: columnMap={'a': [], 'b': [], 'c': [], 'd': []}
> >> In [59]: columnMap['a'].append('something')
> >> In [60]: columnMap
> >> Out[60]: {'a': ['something'], 'b': [], 'c': [], 'd': []}

>
> >> creating the dictionary without using zip, it works as normal.

> On Thu, Apr 30, 2009 at 11:00 AM, Sneaky Wombat <joe.hr...@gmail.com> wrote:
> > quick update,

>
> > #change this line:
> > for (k,v) in zip(header,[[]]*len(header)):
> > #to this line:
> > for (k,v) in zip(header,[[],[],[],[]]):

>
> > and it works as expected. *Something about the [[]]*len(header) is
> > causing the weird behavior. *I'm probably using it wrong, but if
> > anyone can explain why that would happen, i'd appreciate it. *My guess
> > is that it's iterating through the the whole dictionary because of the
> > value on the right in zip().

>
> Readhttp://www.python.org/doc/faq/programming/#how-do-i-create-a-multidim....
> Basically, the multiplication doesn't create new sub-lists, it just
> copies references to the one original empty sublist.
>
> Cheers,
> Chris
> --http://blog.rebertia.com


Reply With Quote
  #6 (permalink)  
Old 04-30-2009, 06:36 PM
Scott David Daniels
Guest
 
Posts: n/a
Default Re: using zip() and dictionaries

Sneaky Wombat wrote:
> quick update,
>
> #change this line:
> for (k,v) in zip(header,[[]]*len(header)):
> #to this line:
> for (k,v) in zip(header,[[],[],[],[]]):
>
> and it works as expected. Something about the [[]]*len(header) is
> causing the weird behavior. I'm probably using it wrong, but if
> anyone can explain why that would happen, i'd appreciate it.


I'll bet the output below explains it:
header = 'a', 'b', 'c', 'd'
print [id(x) for x in [[]] * len(header)]
print [id(x) for x in [[],[],[],[]]]
and (what I think you want):
print [id(x) for x in [[] for x in header]]

So, I think you should use:
columnMap = dict(zip(header, ([] for x in header)))

--Scott David Daniels
Scott.Daniels@Acm.Org
Reply With Quote
  #7 (permalink)  
Old 04-30-2009, 06:48 PM
Arnaud Delobelle
Guest
 
Posts: n/a
Default Re: using zip() and dictionaries

Sneaky Wombat <joe.hrbek@gmail.com> writes:

> I'm really confused by what is happening here. If I use zip(), I
> can't update individual dictionary elements like I usually do. It
> updates all of the dictionary elements. It's hard to explain, so here
> is some output from an interactive session:
>
> In [52]: header=['a','b','c','d']
> In [53]: columnMap={}
> In [54]: for (k,v) in zip(header,[[]]*len(header)):
> ....: #print "%s,%s"%(k,v)
> ....: columnMap[k] = v
> ....:
> In [55]: columnMap
> Out[55]: {'a': [], 'b': [], 'c': [], 'd': []}
> In [56]: columnMap['a'].append('something')
> In [57]: columnMap
> Out[57]:
> {'a': ['something'],
> 'b': ['something'],
> 'c': ['something'],
> 'd': ['something']}
>
> Why does ['something'] get attached to all columnMap elements instead
> of just element 'a'?
>
>
> In [58]: columnMap={'a': [], 'b': [], 'c': [], 'd': []}
> In [59]: columnMap['a'].append('something')
> In [60]: columnMap
> Out[60]: {'a': ['something'], 'b': [], 'c': [], 'd': []}
>
> creating the dictionary without using zip, it works as normal.


It's a FAQ:

http://www.python.org/doc/faq/progra...mensional-list

--
Arnaud
Reply With Quote
  #8 (permalink)  
Old 04-30-2009, 07:54 PM
Simon Forman
Guest
 
Posts: n/a
Default Re: using zip() and dictionaries

On Apr 30, 2:00*pm, Sneaky Wombat <joe.hr...@gmail.com> wrote:
> quick update,
>
> #change this line:
> for (k,v) in zip(header,[[]]*len(header)):
> #to this line:
> for (k,v) in zip(header,[[],[],[],[]]):
>
> and it works as expected. *Something about the [[]]*len(header) is
> causing the weird behavior. *I'm probably using it wrong, but if
> anyone can explain why that would happen, i'd appreciate it. *My guess
> is that it's iterating through the the whole dictionary because of the
> value on the right in zip().
>
> On Apr 30, 12:45*pm, Sneaky Wombat <> wrote:
>
> > I'm really confused by what is happening here. *If I use zip(), I
> > can't update individual dictionary elements like I usually do. *It
> > updates all of the dictionary elements. *It's hard to explain, so here
> > is some output from an interactive session:

>
> > In [52]: header=['a','b','c','d']
> > In [53]: columnMap={}
> > In [54]: for (k,v) in zip(header,[[]]*len(header)):
> > * *....: * * #print "%s,%s"%(k,v)
> > * *....: * * columnMap[k] = v
> > * *....:
> > In [55]: columnMap
> > Out[55]: {'a': [], 'b': [], 'c': [], 'd': []}
> > In [56]: columnMap['a'].append('something')
> > In [57]: columnMap
> > Out[57]:
> > {'a': ['something'],
> > *'b': ['something'],
> > *'c': ['something'],
> > *'d': ['something']}

>
> > Why does ['something'] get attached to all columnMap elements instead
> > of just element 'a'?

>
> > In [58]: columnMap={'a': [], 'b': [], 'c': [], 'd': []}
> > In [59]: columnMap['a'].append('something')
> > In [60]: columnMap
> > Out[60]: {'a': ['something'], 'b': [], 'c': [], 'd': []}

>
> > creating the dictionary without using zip, it works as normal.

>
>


You figured out your original question, I just wanted to point out
that your code as posted is less efficient than it could be.
Rather than creating a list of empty lists to feed to zip() you could
just assign a new empty list to columnMap in your loop body, like so:

In [54]: for k in header:
....: columnMap[k] = []

That avoids creating a list of lists just to pass to zip() the call to
zip() too.
~S
Reply With Quote
 
Reply

Thread Tools
Display Modes

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 Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 02:41 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.