在python中使用逆字典简化代码

问题描述

考虑定义某些键顺序的映射 my_map,以及将相同键映射到某些值的字典 my_dict

my_map = {'x' : 2,'y' : 0,'z' : 1}
my_dict = {'x' : 'foo','z' : 'bar','y' : 'baz'}

我想使用 my_dict 定义的顺序获取 my_map 值的有序列表。我到达那里的最佳方法是:

inv_map = {v: k for k,v in my_map.items()}
ordered_list = [my_dict[k] for k in [inv_map[d] for d in range(len(my_map))]]

有没有一种不那么笨拙的方法来做同样的事情?

解决方法

您可以使用 sorted 函数按值对地图进行排序,然后进行转换:

[my_dict[k] for k in sorted(my_map,key=lambda key: my_map[key])]

至少干净一些!

让我们确保它有效:

>>> my_map = {'x' : 2,'y' : 0,'z' : 1}
>>> my_dict = {'x' : 'foo','z' : 'bar','y' : 'baz'}
>>> [my_dict[k] for k in sorted(my_map,key=lambda key: my_map[key])]
['baz','bar','foo']
,

您实际上可以在这里使用 dict.get 非常有效地使用 sorted:

[my_dict[k] for k in sorted(my_map,key=my_map.get)]

在行动:

>>> my_map = {'x' : 2,key=my_map.get)]
['baz','foo']
,

视情况而定,您可以初始化最终列表并将项目传递到所需位置

result = [None] * len(my_dict)

for k,v in my_dict.items():
    result[my_map[k]] = v
,

还有另一种变体(我认为它与已经提出的解决方案不同):

[x[1] for x in sorted(my_dict.items(),key=lambda elem: my_map[elem[0]])]

测试代码:

my_map = {'x' : 2,'z' : 1}
my_dict = {'x' : 'foo','y' : 'baz'}

print(my_dict.items())

sorted_result=[x[1] for x in sorted(my_dict.items(),key=lambda elem: my_map[elem[0]])]

print(sorted_result)

或者有点不同:

sorted_result=list(zip(*sorted(my_dict.items(),key=lambda elem: my_map[elem[0]])))[1]

我想使用 zip() 将元组列表拆分为 2 个列表,但在 Python 3 中 zip() 返回 iterator(不是 list),所以(如 Transpose/Unzip Function (inverse of zip)? 中建议的那样)我将它包裹在 list()

,

您可以将 timessorted 中的值一起使用,并使用一个键函数将它们与 my_dict 中的值进行排序

my_map

如果排序错误,您可以使用 ordered_list = sorted(my_dict.values(),key=lambda s:my_map[{v: k for k,v in my_dict.items()}[s]])