Python从不同长度的多个列表中获取唯一对

时间:2016-02-08 13:24:43

标签: python list itertools

假设在Python中我有3个列表:a, b, c可变长度。例如:

a=[1,2,3]
b=[4,5,6]
c=[7,8]

我想获得上面3个列表的两个元素的每个独特组合,i。即

[1,4],[1,5],[1,6],[1,7],[1,8],[2,4],[2,5]...并且不是3个列表的唯一组合(例如[1,4,7],[1,4,8],...)。

我使用itertools查看了solution here,这对于2个列表来说非常好;但是,当包含n列表时,此解决方案不再有效,因为唯一组合的长度为n

以下是我的尝试:

import itertools

a=[1,2,3]
b=[4,5,6]
c=[7,8]

d=list(itertools.product(a,b,c))

[(1, 4, 7), (1, 4, 8), (1, 5, 7), (1, 5, 8), (1, 6, 7), (1, 6, 8), (2, 4, 7), (2, 4, 8), (2, 5, 7), (2, 5, 8), (2, 6, 7), (2, 6, 8), (3, 4, 7), (3, 4, 8), (3, 5, 7), (3, 5, 8), (3, 6, 7), (3, 6, 8)]

注意:上面只是一个示例,解决方案应该适用于n可变长度列表,并且可能在不同的列表中具有相同的值...任何关于我如何做的想法将不胜感激! :)

编辑:正如@SirParselot所说,元素必须来自不同的列表

2 个答案:

答案 0 :(得分:3)

您需要(a, b, c)中每对列表的Cartesian product,因此首先您需要itertools.combinations来生成列表对,然后itertools.product来创建所需的列表输出元组。

from itertools import combinations, product

def pairs(*lists):
    for t in combinations(lists, 2):
        for pair in product(*t):
            yield pair

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8]

for pair in pairs(a, b, c):
    print(pair)

<强>输出

(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)
(1, 7)
(1, 8)
(2, 7)
(2, 8)
(3, 7)
(3, 8)
(4, 7)
(4, 8)
(5, 7)
(5, 8)
(6, 7)
(6, 8)

这是一个处理重复元素的新版本。如果元组中的两个项彼此相等,它不返回元组,并且它还通过将pairs的输出馈送到集合中来消除输出中的重复元组。这是合理有效的,因为pairs是一个生成器,所以在找到它们时会删除重复项。

from itertools import combinations, product

def pairs(*lists):
    for t in combinations(lists, 2):
        for pair in product(*t):
            #Don't output pairs containing duplicated elements 
            if pair[0] != pair[1]:
                yield pair

a = [1, 2, 3]
b = [3, 4, 5]
c = [5, 6]

#Feed the output of `pairs` into a set to eliminate duplicate tuples
output = set(pairs(a, b, c))
for pair in sorted(output):
    print(pair)

<强>输出

(1, 3)
(1, 4)
(1, 5)
(1, 6)
(2, 3)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)
(4, 5)
(4, 6)
(5, 6)

答案 1 :(得分:0)

我想你应该做的是使用两个列表的工作解决方案来完成n列表。基本上,您可以将输入转换为列表列表,并执行:

for index, left_list in enumerate(list_of_lists):
        other_lists = (list_of_lists[0:index] + list_of_lists[index+1:])
        right_list = [i for sublist in other_lists for i in sublist]
        print(list(itertools.product(left_list, right_list)))