b = [{'id': 'a'}, {'id': 'c'}, {'id': 'b'}, {'id': 'e'}]
我需要这个成为:
b = [{'id': 'a'}, {'id': 'c'}, {'id': 'e'}, {'id': 'b'}]
此新订单由另一个列表定义。
my_filter = ['a', 'c', 'e', 'b']
...正如您所看到的,带有dicts的列表现在具有一系列在my_filter
变量上显示的ID。
我能够重新排序,但是使用一堆fors并不会有效率。你知道更好的方法吗?我已经知道如何sort a list of dictionaries by values of the dictionary,但我需要这个顺序由另一个列表定义。
编辑:my_filter
被命名为filter
,我在Dave Kirby's recommendation后更改,因为它是内置的。由于某些答案中仍有filter
,因此如果您在某些答案中看到filter
,则可以避免混淆。
答案 0 :(得分:7)
>>> sorted(b, key=lambda x: filter.index(x['id']))
[{'id': 'a'}, {'id': 'c'}, {'id': 'e'}, {'id': 'b'}]
答案 1 :(得分:5)
请记住,Ignacio的解决方案等同于执行您想要避免的嵌套for循环。即它是n ^ 2。更有效的解决方案如下:
>>> filterdict = dict((k,i) for i,k in enumerate(filter))
>>> sorted(b, key=lambda x: filterdict[x['id']])
[{'id': 'a'}, {'id': 'c'}, {'id': 'e'}, {'id': 'b'}]
或:
>>> b.sort(key=lambda x: filterdict[x['id']])
>>> b
[{'id': 'a'}, {'id': 'c'}, {'id': 'e'}, {'id': 'b'}]
就地排序。
编辑: antonakos'解决方案是最好的(2n),如果你的id是唯一的(这可能是一个安全的假设,但你没有指定,所以我不想假设)。这是一种稍微简短的写作方式,以防它更清晰:
>>> d = dict((i['id'], i) for i in b)
>>> [d[key] for key in filter]
[{'id': 'a'}, {'id': 'c'}, {'id': 'e'}, {'id': 'b'}]
答案 2 :(得分:3)
构建反向字典并查找过滤器序列的值:
def order_by_values_for_key(key, dictionaries, values):
rev = {}
for d in dictionaries:
val = d[key]
rev[val] = d
return [ rev[val] for val in values ]
b = [{'id': 'a'}, {'id': 'c'}, {'id': 'b'}, {'id': 'e'}]
filter = ['a', 'c', 'e', 'b']
print order_by_values_for_key('id', b, filter)
使用Python3的字典理解你可以写:
def order_by_values_for_key(key, dictionaries, values):
rev = { d[key] : d for d in dictionaries }
return [ rev[val] for val in values ]
答案 3 :(得分:3)
order = dict((v, i) for (i,v) in enumerate(filter))
sorted(b, key=lambda x:order[x['id']])
这应该比Ignacio的答案更有效,因为字典查找是O(1)而索引(x)是O(n)。
BTW过滤器是内置函数的名称,因此不应将其用作变量名。
答案 4 :(得分:1)
要添加到antonakos和Keither的答案(我没有代表直接评论),字典理解也可以在2.7中获得,并且在这个例子中大约快1/3:
python -mtimeit "{k: i for i,k in enumerate(range(1000))}"
10000 loops, best of 3: 93.5 usec per loop
python -mtimeit "dict((k,i) for i,k in enumerate(range(1000)))"
10000 loops, best of 3: 158 usec per loop