使用单个“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)

python 在itertools中使用product方法来避免嵌套for循环

itertools常用函数

python模块 itertools

Itertools 等效于嵌套循环“for x in xs: for y in ys...”