【问题标题】:Return a list of dictionaries that match the corresponding list of values in python返回与python中对应的值列表匹配的字典列表
【发布时间】:2010-12-01 22:07:54
【问题描述】:

例如,这是我的字典列表:

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

基于列表['blue', 'red', 'green'] 我想返回以下内容:

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

【问题讨论】:

  • 听起来像是功课。在这种情况下,你应该这样标记它。
  • 这不是家庭作业。我只是让列表尽可能简单以便更好地理解。
  • @teggy - 我编辑了你的问题,让它看起来更好。我希望你不要介意。如果您不同意我所做的任何更改,或者您只是想看看如何在 StackOverflow 上格式化代码,您可以自己编辑它。
  • @teggy:好的。请注意,简化案例可能会得到无用的答案。 :) 例如,您的排序列表与字典列表的长度相同,并且没有重复的颜色。如果这不是故意的,下面的一些答案将不起作用。
  • 别忘了选择答案。

标签: python dictionary


【解决方案1】:

这可能有点天真,但它确实有效:

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

【讨论】:

  • 我会说简单直接而不是幼稚
【解决方案2】:

更新:

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

【讨论】:

  • 将按蓝色、绿色、红色的顺序获取它们,这不是我们要求的。
【解决方案3】:

您可以使用任何自定义键功能sort

>>> 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 需要线性时间,因此如果颜色数量可以增加,则转换为更快的键查找。

>>> 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: key= 方法本质上比 cmp= one 更快(幸好在 Py3 中被删除了!)并且 colorkeys 构建是一个值得优化的——所以基本上我没有什么可以添加的了一个单独的答案(做得好!-)。
【解决方案4】:

重复哈托的解决方案:

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

主要区别在于使用列表推导式构建结果

编辑:我在想什么?这显然需要使用 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'}]
>>>

【讨论】:

  • 酷。不确定这种嵌套列表理解是否存在!
【解决方案5】:

这是一个简单的循环函数:

# 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)))

现在,如果您有很多人,那将非常慢。然后你可以只循环一次,但是按颜色建立一个索引:

# 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)))

即使对于非常大的列表,这也会非常快。

【讨论】:

  • 值得注意的是,此解决方案可以处理人员列表大于颜色列表以及多个人具有相同颜色的情况。如果这是一个家庭作业问题(我怀疑),那么这可能没有必要。但是,如果它不是一个家庭作业问题,或者一个关于通用用例的问题,那么这将处理那些通用用例。
【解决方案6】:

给定:

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

你可以这样做:

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]

如果您要使用相同的字典列表但不同的颜色列表多次执行此操作,您需要拆分索引构建并保留索引,这样您就不需要每次都重新构建它.

【讨论】:

    猜你喜欢
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多