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'}]

      

+2


source to share


6 answers


It might be a little naive, but it works:



data = [
    {'name':'John', 'color':'red'},
    {'name':'Bob', 'color':'green'},
    {'name':'Tom', 'color':'blue'}
]
colors = ['blue', 'red', 'green']
result = []

for c in colors:
    result.extend([d for d in data if d['color'] == c])

print result

      

+4


source


Update:



>>> list_ = [{'c': 3}, {'c': 2}, {'c': 5}]
>>> mp = [3, 5, 2]
>>> sorted(list_, cmp=lambda x, y: cmp(mp.index(x.get('c')), mp.index(y.get('c'))))
[{'c': 3}, {'c': 5}, {'c': 2}]

      

+2


source


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'}]

      

+1


source


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'}]
>>>

      

+1


source


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.

0


source


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.

0


source







All Articles