Question

In Python, I've got a list of 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?

Was it helpful?

Solution

You can use a list comprehension:

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

Which follows the format standard format of:

resulting_list = [item_to_return for item in items if condition]

And 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.

OTHER TIPS

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 ]

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"]

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.

I really like to use filter in this sort of situation. It takes a function and an iterable and returns the list of elements where the function returns True (in Python 3.x it returns an iterator).

>>> filter(lambda x: x['id'] == 'someid3', matchings)
<<< [{'domain': 'somedomain3.com', 'id': 'someid3'}]

You could get a list of all domains by using a list comprehension:

>>> [x['domain'] for x in filter(lambda x: x['id'] == 'someid3', matchings)]
<<< ['somedomain3.com']
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top