0

我有两个列表,一个是规范的列表,另一个是当前的列表。我想尝试列表与列表的所有偏差组合。例如:

good = (0,1,2,3)
bad =  (0,10,20,3)

申请运营商后op(good, bad),我应该回来

ret = ((0,1,2,3), (0,10,2,3), (0,10,20,3), (0,1,20,3))

子列表的任何顺序。

我正在使用的列表stty -g是 36 个元素的输出,这些列表相差 16 个元素。

4

2 回答 2

3

压缩好的和坏的列表,将每个结果元组映射到一个集合并将其提供给itertools.product()

from itertools import product

for combo in product(*map(set, zip(good, bad))):
    print(combo)

演示:

>>> good = (0,1,2,3)
>>> bad =  (0,10,20,3)
>>> from itertools import product
>>> for combo in product(*map(set, zip(good, bad))):
...     print(combo)
... 
(0, 1, 2, 3)
(0, 1, 20, 3)
(0, 10, 2, 3)
(0, 10, 20, 3)

这将采用任何大小的输入;不仅是goodand bad,还可以添加ugly

>>> ugly =  (1,2,4,3)
>>> for combo in product(*map(set, zip(good, bad, ugly))):
...     print(combo)
... 
(0, 1, 4, 3)
(0, 1, 2, 3)
(0, 1, 20, 3)
(0, 10, 4, 3)
(0, 10, 2, 3)
(0, 10, 20, 3)
(0, 2, 4, 3)
(0, 2, 2, 3)
(0, 2, 20, 3)
(1, 1, 4, 3)
(1, 1, 2, 3)
(1, 1, 20, 3)
(1, 10, 4, 3)
(1, 10, 2, 3)
(1, 10, 20, 3)
(1, 2, 4, 3)
(1, 2, 2, 3)
(1, 2, 20, 3)

推广到一个函数:

def op(*sequences):
    return product(*map(set, zip(*sequences)))

for combo in op(good, bad):
    print(combo)

for combo in op(good, bad, ugly):
    print(combo)

因为 aset用于从每个组合的输入集合中生成唯一值,所以输出顺序与输入的顺序不同。如果 order 很重要,您可以替换setdupe-removing order-preserving 函数

def unique_with_order(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if x not in seen and not seen_add(x)]

def ordered_op(*sequences):
    return product(*map(unique_with_order, zip(*sequences)))

它产生根据输入顺序排序的输出:

>>> for combo in ordered_op(good, bad):
...     print(combo)
... 
(0, 1, 2, 3)
(0, 1, 20, 3)
(0, 10, 2, 3)
(0, 10, 20, 3)
>>> for combo in ordered_op(bad, good):
...     print(combo)
... 
(0, 10, 20, 3)
(0, 10, 2, 3)
(0, 1, 20, 3)
(0, 1, 2, 3)
于 2013-10-02T20:26:49.670 回答
2

你想要的是每个索引的好或坏值的笛卡尔积,除了当好和坏的值相同时,你只想要其中一个,而不是它的两个副本。

所以,让我们压缩这两个列表,并将每个好==坏的组件减少到一个值:

>>> gb = (([g,b] if g!=b else [g] for (g, b) in zip(good, bad))

然后是笛卡尔积:

>>> ret = itertools.product(*gb)

既然你想要它作为一个元组:

>>> ret = tuple(ret)
>>> print ret
((0, 1, 2, 3), (0, 1, 20, 3), (0, 10, 2, 3), (0, 10, 20, 3))
于 2013-10-02T20:25:57.460 回答