15 May 18:58
Re: Iterate through dictionary values and remove item
From: GTXY20 <gtxy20 <at> gmail.com>
Subject: Re: Iterate through dictionary values and remove item
Newsgroups: gmane.comp.python.tutor
Date: 2008-05-15 16:58:03 GMT
Subject: Re: Iterate through dictionary values and remove item
Newsgroups: gmane.comp.python.tutor
Date: 2008-05-15 16:58:03 GMT
Hi Kent and Bob,
Bob sorry about the previous code snippet (was late) - I had previously been trying to accomplish with the following:
for k,v in d.items():
u=k[0]
b=k[1]
if 'a' in v:
for k,v in d.items():
if k[0] == u:
for vals in v:
if vals == 'b':
v.remove('b')
u=k[0]
b=k[1]
if 'a' in v:
for k,v in d.items():
if k[0] == u:
for vals in v:
if vals == 'b':
v.remove('b')
this as mentioned was not performing very well at all.
Kent, I incorporated your suggestion:
toRemove=set(k[0] for k, v in d.iteritems() if 'b' in v)
for k,v in d.iteritems():
if k[0] in toRemove:
try:
v.remove('b')
except ValueError:
pass
for k,v in d.iteritems():
if k[0] in toRemove:
try:
v.remove('b')
except ValueError:
pass
and the speed and result improved very dramatically. I suspect that I need to get a better handle on the difference between items() and iteritems() and what situations would call for them respectively.
Having said that, Kent I am not 100 percent sure of what you menat when you mention a two-level dict. Can you give me a very brief example?
Thank you so much for your feedback.
G.
On Thu, May 15, 2008 at 7:57 AM, Kent Johnson <kent37 <at> tds.net> wrote:
The main problem is the nested loops. Every time you find an 'a' youOn Thu, May 15, 2008 at 2:40 AM, GTXY20 <gtxy20 <at> gmail.com> wrote:
> Hello all,
>
> I have dictionary like the following:
>
> d={(1,23A):[a,b,c,d], (1,24A):[b,c,d], (2,23A):[a,b], (2,24A):[a,b,c,d]}
>
> I would like to iterate through the dictionary such that if it finds
> the value 'a' in the values of the key that it would remove the value
> 'b' from the values list. In addition if it finds 'a' in the values
> list I would like it to take the first item from the key tuple k[0]
> and and then look through the dictionary for that k[0] value and then
> remove 'b' from its value list even if 'a' is not present in that
> list. So at the end I would like my dictionary to end with:
>
> d={(1,23A):[a,c,d], (1,24A):[c,d], (2,23A):[a], (2,24A):[a,c,d]}
>
> Initally I did the following:
>
> for k,v in d.items():
> u=k[0]
> b=k[1]
> if 'a' in v:
> for k,v in d.items():
> if k[0] == u:
> for values in v:
> if values == 'b':
> v.remove(values)
>
> However this will be a very big dictionary and it ended up running for
> a very long time - in fact I had to kill the process.
search the whole dict for items starting with matching keys. There
are some smaller problems as well - you could use d.iteritems()
instead of d.items() to avoid creating intermediate lists, and there
are better ways to remove 'b' from v.
The first thing I would do is reduce this to two passes over the dict
- the first pass can find the keys, the second to delete 'b' from the
list. For example,
toRemove=set(k[0] for k, v in d.iteritems() if 'b' in v)
for k,v in d.iteritems():
if k[0] in toRemove:
try:
v.remove('b')
except ValueError:
pass
If this is too slow, consider splitting up your keys - make a
two-level dict so you can find all the keys starting with a particular
value by a dict lookup instead of search.
Kent
_______________________________________________ Tutor maillist - Tutor <at> python.org http://mail.python.org/mailman/listinfo/tutor
RSS Feed