简体   繁体   English

返回与python中相应的值列表匹配的字典列表

[英]Return a list of dictionaries that match 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: 基于列表['blue', 'red', 'green']我想返回以下内容:

[{'name': 'Tom',  'color': 'blue' },
 {'name': 'John', 'color': 'red'  },
 {'name': 'Bob',  'color': 'green'}]

This might be a little naieve, 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

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

You can sort using any custom key 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 though, so if the number of colors can grow, then convert to a faster key lookup. list.index虽然需要线性时间,但如果颜色数量增加,则转换为更快的键查找。

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

Riffing on Harto's solution: 重复Harto的解决方案:

>>> 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 in using a list comprehension to build result . 主要区别在于使用列表推导来构建结果

Edit: What was I thinking? 编辑:我在想什么? This clearly calls out for the use of the any() expression: 这清楚地要求使用any()表达式:

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

Here is 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 that will be VERY slow if you have many people. 如果你有很多人,现在这将非常慢。 Then you can loop through them only once, but build an index by color: 然后你只能循环它们一次,但是按颜色构建一个索引:

# Here's 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 quite fast even for really big lists. 即使对于非常大的列表,这也会非常快。

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're going to do this many times with the same list of dictionaries but different lists of colors you'll want to split the index building out and keep the index around so you don't need to rebuild it every time. 如果您要使用相同的词典列表但不同的颜色列表多次执行此操作,则需要将索引构建拆分并保留索引,这样您就不需要每次都重建它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM