[Tutor] if value in list of dictionaries
Peter Otten
__peter__ at web.de
Tue Sep 28 17:41:22 CEST 2010
Norman Khine wrote:
> thanks for the reply, i think i have it now, perhaps it could be done
> better
> >>> topics.sort(key=itemgetter('name'))
> >>> for i, t in enumerate(topics):
> ... for (k, v) in t.iteritems():
> ... if v == 'other':
> ... topics.append(topics.pop(i))
> ...
You should never iterate over a list or dictionary and add or remove items
to it at the same time. That is a recipe for disaster even if it doesn't
fail explicitly*
As Christian Witts explains in the "trouble with list.remove() loop" thread
you will not see all items.
I suggest that you use a better sort key instead:
>>> def sort_key(topic):
... name = topic["name"]
... return name == "other", name
...
>>> topics.sort(key=sort_key)
>>> pprint(topics)
[{'industry': 'travel',
'name': 'assistant-manager',
'value': 'Assistant Manager'},
<snip>
{'industry': 'travel', 'name': 'university', 'value': 'University'},
{'industry': 'travel', 'name': 'other', 'value': 'Other'}]
The above sort_key() checks only the "name" key for an "other" value. It
will return a (True, name) tuple if the name is "other" and (False, name)
else. As
False < True
it ensures that topics with topic["name"] == "other" are placed after all
others. If (like your attempt suggests) you want to check all values instead
of just the one associated with the "name" key use
def sort_key(topic):
return "other" in topic.itervalues(), topic["name"]
Remember that both functions are case-sensitive.
Peter
(*) I'll leave it to Steven D'Aprano to add the fine print ;)
More information about the Tutor
mailing list