在 python 中使用逆向字典简化代码
simplify code using an inverse dictionary in python
考虑一些定义某些键顺序的映射 my_map
,以及一些将相同键映射到某些值的字典 my_dict
:
my_map = {'x' : 2, 'y' : 0, 'z' : 1}
my_dict = {'x' : 'foo', 'z' : 'bar', 'y' : 'baz'}
我想使用 my_map
定义的顺序获取 my_dict
值的有序列表。我到达那里的最佳方法是:
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
的值一起使用,并使用一个关键函数将它们与来自 my_map
的值一起排序
ordered_list = sorted(my_dict.values(), key=lambda s:my_map[{v: k for k, v in my_dict.items()}[s]])
如果排序错误,您可以使用 reverse=True
您可以使用 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']
根据情况您可以初始化最终列表并将项目传递到需要的位置
result = [None] * len(my_dict)
for k, v in my_dict.items():
result[my_map[k]] = v
您实际上可以在这里非常有效地使用排序 dict.get
:
[my_dict[k] for k in sorted(my_map, key=my_map.get)]
进行中:
>>> 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=my_map.get)]
['baz', 'bar', 'foo']
还有一个变体(我认为它与已经提出的解决方案不同):
[x[1] for x in sorted(my_dict.items(), key=lambda elem: my_map[elem[0]])]
测试代码:
my_map = {'x' : 2, 'y' : 0, 'z' : 1}
my_dict = {'x' : 'foo', 'z' : 'bar', '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]
I wanted to use zip()
to split a list of tuples into 2 lists, but in Python 3 zip()
returns iterator (not a list), so (as suggested in Transpose/Unzip Function (inverse of zip)?) I wrapped it in list()
考虑一些定义某些键顺序的映射 my_map
,以及一些将相同键映射到某些值的字典 my_dict
:
my_map = {'x' : 2, 'y' : 0, 'z' : 1}
my_dict = {'x' : 'foo', 'z' : 'bar', 'y' : 'baz'}
我想使用 my_map
定义的顺序获取 my_dict
值的有序列表。我到达那里的最佳方法是:
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
的值一起使用,并使用一个关键函数将它们与来自 my_map
ordered_list = sorted(my_dict.values(), key=lambda s:my_map[{v: k for k, v in my_dict.items()}[s]])
如果排序错误,您可以使用 reverse=True
您可以使用 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']
根据情况您可以初始化最终列表并将项目传递到需要的位置
result = [None] * len(my_dict)
for k, v in my_dict.items():
result[my_map[k]] = v
您实际上可以在这里非常有效地使用排序 dict.get
:
[my_dict[k] for k in sorted(my_map, key=my_map.get)]
进行中:
>>> 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=my_map.get)]
['baz', 'bar', 'foo']
还有一个变体(我认为它与已经提出的解决方案不同):
[x[1] for x in sorted(my_dict.items(), key=lambda elem: my_map[elem[0]])]
测试代码:
my_map = {'x' : 2, 'y' : 0, 'z' : 1}
my_dict = {'x' : 'foo', 'z' : 'bar', '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]
I wanted to use
zip()
to split a list of tuples into 2 lists, but in Python 3zip()
returns iterator (not a list), so (as suggested in Transpose/Unzip Function (inverse of zip)?) I wrapped it inlist()