繁体   English   中英

两个列表的差异的所有组合

[英]all combinations of differences of two lists

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

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个元素。

压缩好列表和坏列表,将每个结果元组映射到一个集合,并将其馈送到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)

这将需要任何大小的输入; 不只是goodbad ,但你可以添加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用于从输入的每个组合集合中产生唯一值,所以输出顺序与输入的顺序不同。 如果订单很重要,则可以使用取消伪造的订单保留功能代替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)

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

因此,让我们压缩两个列表,并将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))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM