我有两个列表,一个是规范的好的列表,另一个是当前的错误的列表。我想尝试好列表与好列表的所有偏差组合。例如:
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个元素。
答案 0 :(得分: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)
这将采用任何大小的输入;不仅仅是good
和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)
因为set
用于从每个组合输入中生成唯一值,所以输出顺序与输入顺序不同。如果订单很重要,您可以使用dupe-removing order-preserving function代替set
:
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)
答案 1 :(得分:2)
你想要的是每个指数的好坏价值的笛卡尔积,除了当好的和坏的具有相同的价值时,你只需要其中一个,而不是两个副本。
所以,让我们将这两个列表压缩,并将good == bad的每个组件减少为单个值:
>>> 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))