【发布时间】:2019-10-01 11:00:20
【问题描述】:
我需要在 l 的项目列表中迭代长度为 2 的组合的 (a, b) 和 (c, d) 对,并具有以下约束:
- 不成对重复:如果
(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?
【问题讨论】:
-
数字 4 未出现在您的列表中
l。这是正确的吗? -
不,不是,我刚刚修好了,谢谢指出!
标签: python list combinations combinatorics