Python 两个列表差异的所有组合
我有两个列表,一个是规范的好的列表,另一个是当前的坏的列表。我想尝试坏列表与好列表的所有偏差组合。例如:Python 两个列表差异的所有组合,python,combinatorics,Python,Combinatorics,我有两个列表,一个是规范的好的列表,另一个是当前的坏的列表。我想尝试坏列表与好列表的所有偏差组合。例如: good = (0,1,2,3) bad = (0,10,20,3) 在应用操作符op(好的,坏的)之后,我应该回去了 ret = ((0,1,2,3), (0,10,2,3), (0,10,20,3), (0,1,20,3)) 以子列表的任何顺序 我正在处理的列表是stty-g的输出,它是36个元素,列表之间相差16个元素。您需要的是每个索引的好值或坏值的笛卡尔乘积,除了当好值和坏值
good = (0,1,2,3)
bad = (0,10,20,3)
在应用操作符op(好的,坏的)
之后,我应该回去了
ret = ((0,1,2,3), (0,10,2,3), (0,10,20,3), (0,1,20,3))
以子列表的任何顺序
我正在处理的列表是stty-g的输出,它是36个元素,列表之间相差16个元素。您需要的是每个索引的好值或坏值的笛卡尔乘积,除了当好值和坏值相同时,您只需要其中一个,而不是两个副本 因此,让我们压缩这两个列表,并将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))
你想要的是每个索引上好的或坏的值的笛卡尔积,除了当好的和坏的值相同时,你只想要其中一个,而不是它的两个副本 因此,让我们压缩这两个列表,并将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))
压缩好的和坏的列表,将每个结果元组映射到一个集合,并将其馈送到
itertools.product()
:
演示:
这将需要任何大小的输入;不仅仅是好的
和坏的
,还可以添加丑陋的
:
>>> 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
替换为:
它根据输入的顺序生成有序的输出:
>>> 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)
压缩好的和坏的列表,将每个结果元组映射到一个集合,并将其馈送到
itertools.product()
:
演示:
这将需要任何大小的输入;不仅仅是好的
和坏的
,还可以添加丑陋的
:
>>> 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
替换为:
它根据输入的顺序生成有序的输出:
>>> 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)