如何以其索引的元组作为键可读且有效地创建可迭代组合的字典?

How to readably and efficeintly create a dictionary of iterable combinations with a tuple of their indices as keys?

所以我有一些代码可以工作,但充其量很难阅读,而且我觉得效率低下,因为它使用了两个列表推导式,而一个列表推导式就足够了。

我需要的是创建一个包含 alpha 中字母的所有 n 组合的字典,每个项目的字典键是 [=13] 中索引的元组=] 用于组合中的元素。这应该适用于任何 n:

n=2

from itertools import combinations 

alpha = "abcde" 
n = 2

D = {tuple([c_i[0] for c_i in comb]): tuple([c_i[1] for c_i in comb]) 
     for comb in combinations(enumerate(alpha), n)}

>>>{(0, 1): ('a', 'b'),
 (0, 2): ('a', 'c'),
 (0, 3): ('a', 'd'),
 (0, 4): ('a', 'e'),
 (1, 2): ('b', 'c'),
 (1, 3): ('b', 'd'),
 (1, 4): ('b', 'e'),
 (2, 3): ('c', 'd'),
 (2, 4): ('c', 'e'),
 (3, 4): ('d', 'e')}

n=3

from itertools import combinations 

alpha = "abcde" 
n = 3

D = {tuple([c_i[0] for c_i in comb]): tuple([c_i[1] for c_i in comb]) 
     for comb in combinations(enumerate(alpha), n)}

>>>{(0, 1, 2): ('a', 'b', 'c'),
 (0, 1, 3): ('a', 'b', 'd'),
 (0, 1, 4): ('a', 'b', 'e'),
 (0, 2, 3): ('a', 'c', 'd'),
 (0, 2, 4): ('a', 'c', 'e'),
 (0, 3, 4): ('a', 'd', 'e'),
 (1, 2, 3): ('b', 'c', 'd'),
 (1, 2, 4): ('b', 'c', 'e'),
 (1, 3, 4): ('b', 'd', 'e'),
 (2, 3, 4): ('c', 'd', 'e')}

这是按预期工作的,但我想知道是否有更易读的实现,或者我不需要单独理解的实现 [c_i[0] for c_i in comb][c_i[1] for c_i in comb] 因为这感觉效率低下。

注意:这是一个更复杂问题的最小案例表示,其中 alpha 的元素是昂贵函数的参数,我想将 f(alpha[i], alpha[j], alpha[k]) 的输出存储在字典中以用于无需重新计算即可轻松查找:ans = D[(i, j, k)]

避免看似冗余的元组键值形成的一种方法是使用 zipassignment expression:

from itertools import combinations 
alpha = "abcde" 
n = 2
D = {(k:=list(zip(*comb)))[0]:k[1] for comb in combinations(enumerate(alpha), n)}

输出:

{(0, 1): ('a', 'b'), (0, 2): ('a', 'c'), (0, 3): ('a', 'd'), (0, 4): ('a', 'e'), (1, 2): ('b', 'c'), (1, 3): ('b', 'd'), (1, 4): ('b', 'e'), (2, 3): ('c', 'd'), (2, 4): ('c', 'e'), (3, 4): ('d', 'e')}

试试这个:(我觉得它比另一个答案简单得多,但那个也很有效)

from itertools import combinations 

alpha = "abcde" 
n = 2

print({key: tuple([alpha[i] for i in key]) for key in combinations(range(len(alpha)), n)})

输出:

{(0, 1): ('a', 'b'), (0, 2): ('a', 'c'), (0, 3): ('a', 'd'), (0, 4): ('a', 'e'), (1, 2): ('b', 'c'), (1, 3): ('b', 'd'), (1, 4): ('b', 'e'), (2, 3): ('c', 'd'), (2, 4): ('c', 'e'), (3, 4): ('d', 'e')}