Reputation: 38203
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?
Upvotes: 5
Views: 1540
Reputation: 53879
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']
Upvotes: 0
Reputation: 91722
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.
Upvotes: 7
Reputation: 392060
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 ]
Upvotes: 2
Reputation: 449
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"]
Upvotes: 1
Reputation: 242150
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.
Upvotes: 0