使用单个“for”循环或使用“itertools”库来反转字典
Posted
技术标签:
【中文标题】使用单个“for”循环或使用“itertools”库来反转字典【英文标题】:Reverse a dictionary using single "for" loop or using "itertools" library 【发布时间】:2018-02-27 23:19:20 【问题描述】:我有一本这样的列表字典:
my_dict =
'key_a': [1, 3, 4],
'key_b': [0, 2],
我想像这样创建一个反向查找字典:
reverse_dict =
0: 'key_b',
1: 'key_a',
2: 'key_b',
3: 'key_a',
4: 'key_a',
我有一个解决方案的工作版本:
reverse_dict = elem: key for key, a_list in my_dict.items() for elem in a_list
但想知道是否有人可以提供不使用双重 for
的替代答案,因为我觉得它失去了可读性。所以我更喜欢有一个 for
循环或使用类似 itertools 或函数式编程中的函数
【问题讨论】:
重复键怎么办?获胜的最后一个键? 你的代码在这双眼睛里看起来很完美。 我们可以假设列表不会有重复的元素 这是函数式编程。 你拥有的代码是实现它的pythonic方式,与你可能用Python编写的各种嵌套单行相比,它非常简单。我在这里没有看到任何可读性问题 【参考方案1】:您使用字典理解的解决方案是实现它的 Pythonic 方式。
但是,作为您要求的单个for
循环的替代方案,这里是使用zip()
、itertools.repeat()
和itertools.chain.from_iterable()
的功能性循环,但我怀疑它在可读性方面比你的解决方案更好:
my_dict =
'key_a': [1, 3, 4],
'key_b': [0, 2],
from itertools import chain, repeat
new_dict = dict(chain.from_iterable(zip(v, repeat(k)) for k, v in my_dict.items()))
new_dict
的位置:
0: 'key_b', 1: 'key_a', 2: 'key_b', 3: 'key_a', 4: 'key_a'
【讨论】:
从 cmets 和收到的答案中可以清楚地看出,可读性不是我的代码的问题。我不想删除我的问题,因为它可能对其他人有用。我会接受这个答案,因为它显示了根据要求对 itertools 的最佳使用【参考方案2】:>>> from itertools import chain
>>> dict(chain.from_iterable(map(lambda k: map(lambda j:(j, k), my_dict.get(k)), my_dict)))
1: 'key_a', 3: 'key_a', 4: 'key_a', 0: 'key_b', 2: 'key_b'
没有 for 循环。它显然不是更具可读性
另一个基于@MoinuddinQuadri 的想法
>>> from itertools import chain, repeat
>>> dict(chain.from_iterable(map(lambda k: zip(my_dict[k], repeat(k)), my_dict)))
1: 'key_a', 3: 'key_a', 4: 'key_a', 0: 'key_b', 2: 'key_b'
【讨论】:
非常不需要的使用 lambda 和map
来删除 for
循环。但仍然是“+1”,因为 OP 只想减少它们
@MoinuddinQuadri,这是一个愚蠢的问题,但将这些想法抛诸脑后,看看有什么遗漏会很有趣【参考方案3】:
这是一个没有明确的 for 循环。不过真的不推荐(map
中的副作用,这对许多人来说是禁忌):
>>> import itertools as it
>>> out =
>>> any(map(out.update, it.starmap(dict.fromkeys, map(reversed, my_dict.items()))))
False
>>> out
1: 'key_a', 3: 'key_a', 4: 'key_a', 0: 'key_b', 2: 'key_b'
【讨论】:
地图中的副作用确实是一个禁忌,所以只是向上取整+0.7以上是关于使用单个“for”循环或使用“itertools”库来反转字典的主要内容,如果未能解决你的问题,请参考以下文章
使用 Itertools 和 For 循环创建水平条 (Python)
Python for 循环偏移 (Itertools.product)