Returns a list of dictionaries matching the corresponding list of values in python
For example, this is my list of dictionaries:
[{'name': 'John', 'color': 'red' },
{'name': 'Bob', 'color': 'green'},
{'name': 'Tom', 'color': 'blue' }]
Based on the list, ['blue', 'red', 'green']
I want to return the following:
[{'name': 'Tom', 'color': 'blue' },
{'name': 'John', 'color': 'red' },
{'name': 'Bob', 'color': 'green'}]
source to share
You can use sort to use any special function.
>>> people = [
{'name': 'John', 'color': 'red'},
{'name': 'Bob', 'color': 'green'},
{'name': 'Tom', 'color': 'blue'},
]
>>> colors = ['blue', 'red', 'green']
>>> sorted(people, key=lambda person: colors.index(person['color']))
[{'color': 'blue', 'name': 'Tom'}, {'color': 'red', 'name': 'John'}, {'color': 'green', 'name': 'Bob'}]
list.index takes linear time, so if the number of colors can increase then convert to quick search for keys.
>>> colorkeys = dict((color, index) for index, color in enumerate(colors))
>>> sorted(people, key=lambda person: colorkeys[person['color']])
[{'color': 'blue', 'name': 'Tom'}, {'color': 'red', 'name': 'John'}, {'color': 'green', 'name': 'Bob'}]
source to share
Riffing by Harto's solution:
>>> from pprint import pprint
>>> [{'color': 'red', 'name': 'John'},
... {'color': 'green', 'name': 'Bob'},
... {'color': 'blue', 'name': 'Tom'}]
[{'color': 'red', 'name': 'John'}, {'color': 'green', 'name': 'Bob'}, {'color':
'blue', 'name': 'Tom'}]
>>> data = [
... {'name':'John', 'color':'red'},
... {'name':'Bob', 'color':'green'},
... {'name':'Tom', 'color':'blue'}
... ]
>>> colors = ['blue', 'red', 'green']
>>> result = [d for d in data for c in colors if d['color'] == c]
>>> pprint(result)
[{'color': 'red', 'name': 'John'},
{'color': 'green', 'name': 'Bob'},
{'color': 'blue', 'name': 'Tom'}]
>>>
The main difference is the use of a list comprehension to build the result.
Edit: What was I thinking? This explicitly requires the use of the any () expression:
>>> from pprint import pprint
>>> data = [{'name':'John', 'color':'red'}, {'name':'Bob', 'color':'green'}, {'name':'Tom', 'color':'blue'}]
>>> colors = ['blue', 'red', 'green']
>>> result = [d for d in data if any(d['color'] == c for c in colors)]
>>> pprint(result)
[{'color': 'red', 'name': 'John'},
{'color': 'green', 'name': 'Bob'},
{'color': 'blue', 'name': 'Tom'}]
>>>
source to share
Here's a simple loop function:
# Heres the people:
people = [{'name':'John', 'color':'red'},
{'name':'Bob', 'color':'green'},
{'name':'Tom', 'color':'blue'}]
# Now we can make a method to get people out in order by color:
def orderpeople(order):
for color in order:
for person in people:
if person['color'] == color:
yield person
order = ['blue', 'red', 'green']
print(list(orderpeople(order)))
Now it will be VERY slow if you have a lot of people. Then you can skip them just once, but build the index by color:
# Here the people:
people = [{'name':'John', 'color':'red'},
{'name':'Bob', 'color':'green'},
{'name':'Tom', 'color':'blue'}]
# Now make an index:
colorindex = {}
for each in people:
color = each['color']
if color not in colorindex:
# Note that we want a list here, if several people have the same color.
colorindex[color] = []
colorindex[color].append(each)
# Now we can make a method to get people out in order by color:
def orderpeople(order):
for color in order:
for each in colorindex[color]:
yield each
order = ['blue', 'red', 'green']
print(list(orderpeople(order)))
This will be pretty fast even for really large lists.
source to share
Given:
people = [{'name':'John', 'color':'red'}, {'name':'Bob', 'color':'green'}, {'name':'Tom', 'color':'blue'}]
colors = ['blue', 'red', 'green']
you can do something like this:
def people_by_color(people, colors):
index = {}
for person in people:
if person.has_key('color'):
index[person['color']] = person
return [index.get(color) for color in colors]
If you are going to do this many times with the same list of dictionaries but different color lists, you need to split the index build and store the index so you don't have to rebuild it every time.
source to share