我需要遍历项目列表(a, b)
中的长度为2的组合对(c, d)
和l
,并具有以下约束:
(a, b)
,则不会产生(b, a)
(a, b)
,(c, d)
已经出现,那么(c, d)
,(a, b)
将不会产生a != c and a != d and b != c and b != d
例如,使用
l = [0, 1, 2, 3, 4]
这对应该是:
(0, 1), (2, 3)
(0, 1), (2, 4)
(0, 1), (3, 4)
(0, 2), (1, 3)
(0, 2), (1, 4)
(0, 2), (3, 4)
(0, 3), (1, 2)
(0, 3), (1, 4)
(0, 3), (2, 4)
(0, 4), (1, 2)
(0, 4), (1, 3)
(0, 4), (2, 3)
(1, 2), (3, 4)
(1, 3), (2, 4)
(1, 4), (2, 3)
在示例中我使用了整数,但是,我对更通用的解决方案感兴趣(尽管在我的特定情况下,这些项是列表)。
这是我想出的解决方案:
import itertools
used = set()
for (a, b) in itertools.combinations(l, 2):
used.add((a, b))
for (c, d) in itertools.combinations(l, 2):
if a == c or a == d or b == c or b == d:
continue
if (c, d) in used:
continue
# do stuff...
pass
除了麻烦之外,此解决方案还需要附加集used
。在实际的实现中,我使用enumerate(l)
而不是l
并将项目的索引放在集合中的元组中,并尝试使用索引更快地过滤选项...但是没有进行管理使其变得更好。
如何使它更高效,并且可能更优雅/ Pythonic?
答案 0 :(得分:2)
一个想法可能是首先生成元组的所有组合,然后对其进行过滤:
l = [0, 1, 2, 3, 4]
aa = list(itertools.combinations(list(itertools.combinations(l, 2)), 2))
[(a,b) for a,b in aa if set(a).isdisjoint(b)]