views:

210

answers:

4

In Python, I've got a list if dictionaries that looks like this:

matchings = [
    {'id': 'someid1', 'domain': 'somedomain1.com'},
    {'id': 'someid2', 'domain': 'somedomain2.com'},
    {'id': 'someid3', 'domain': 'somedomain3.com'}
]

and, I have a variable:

the_id = 'someid3'

What's the most efficient way to retrieve the domain value of the item?

+5  A: 

You can use a list comprehension:

domains = [matching['domain'] for matching in matchings if matching['id'] == the_id]

This basically encapsulates all the following functionality:

domains = []
for matching in matchings:
    if matching['id'] == the_id:
        domains.append(matching['domain'])

All that functionality is represented in a single line using list comprehensions.

Soviut
Perfect, thanks!
Nick Sergeant
Perfect it may be, but is it efficient? What's the length of matchings? Take a look at S.Lott's answer too.
ΤΖΩΤΖΙΟΥ
Is there some reason to use such a long names? `[m['domain'] for m in matchings if m['id'] == the_id]`
J.F. Sebastian
I suspect that the request for "efficiency" was more to do with a nice, clean way to do it.
Soviut
Yes, specifically, the code will be used in ZPT, where I don't have access to a typical Pythonic environment, and am very limited. This works perfectly, in that sense.
Nick Sergeant
+1  A: 

The fact that there are dictionaries in the list doesn't really matter - the problem reduces to finding an item in a list where some property is true. To that end, some variation on @Soviut's answer is the way to go: loop or list comprehension, examining each of the items until a match is found. There's no inherent ordering of the items, so you couldn't even rely on something as helpful as bisect.

Blair Conrad
A: 

The best I can figure is to do an explicit search. This is one area where I get disappointed in Python is that it doesn't give you a strong set of decoupled building blocks like in the C++ STL algorithms

[d["domain"] for d in matchings if d["id"] == "someid3"]
Ed
+1  A: 

I'd restructure matchings.

from collections import defaultdict
matchings_ix= defaultdict(list)
for m in matchings:
    matchings_ix[m['id']].append( m )

Now the most efficient lookup is

matchings_ix[ d ]
S.Lott