两个单独列表的单独组合,彼此保持对应/依赖性

时间:2019-03-20 19:44:04

标签: python itertools

我有两个长度相同的列表,它们具有一对一的对应关系:

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

我想分别查找这两个列表的组合。但是,两个列表的组合元素的索引必须相同。

例如,如果我这样做:

list(itertools.combinations(a,2))

我可能会得到

[(1,2),(1,3),(1,4),(3,2),(4,2),(4,3)]  

我本来可以

[(2,1),(3,1),(4,1),(2,3),(2,4),(3,4)]

也是因为两者相同。

所以无论我得到什么组合,我都希望第二个列表也组合相同的索引。

如果

list(itertools.combinations(a,2))

给我

[(1,2),(1,3),(1,4),(3,2),(4,2),(4,3)]

然后

list(itertools.combinations(b,2))

应该给我

[(6,7),(6,8),(6,9),(8,7),(9,7),(9,8)]

或者如果

list(itertools.combinations(a,2))

给我

[(2,1),(3,1),(4,1),(2,3),(2,4),(3,4)]

然后

list(itertools.combinations(b,2))

应该给我

[(7,6),(8,6),(9,6),(7,8),(7,9),(8,9)]

5 个答案:

答案 0 :(得分:1)

您可以查看源代码,以从列表的索引而不是列表的值告诉您它正在工作。因此,尽管对于同一列表,组合的输出始终是相同的-反转列表的顺序显然会为组合提供不同的输出。

为什么在传递列表时不对列表进行排序,以使它们始终按数字顺序递增,从而可以解决问题。

a = [4,3,2,1]

list(combinations(a,2))
[(4, 3), (4, 2), (4, 1), (3, 2), (3, 1), (2, 1)]

list(combinations(sorted(a),2))
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

https://docs.python.org/3/library/itertools.html#itertools.combinations

答案 1 :(得分:1)

您可以对索引生成组合,然后对a和b进行索引。例如:

a = [1,2,3,4]
b = [6,7,8,9]
for i0,i1 in itertools.combinations(range(len(a)), 2):
  print("{0},{1}  -->  {2},{3}".format(a[i0],a[i1],b[i0],b[i1]))


1,2  -->  6,7
1,3  -->  6,8
1,4  -->  6,9
2,3  -->  7,8
2,4  -->  7,9
3,4  -->  8,9

答案 2 :(得分:1)

从官方python itertools documentation

“组合是按字典顺序排序的。因此,如果输入iterable被排序,则组合元组将按排序顺序生成。”

因此,对于排序列表,从第一个值开始,顺序将始终相同。

答案 3 :(得分:0)

此处的关键是使用itertools.permutations而不是itertools.combinations。这是一种可能的实现,它可以通过一次计算排列来节省一些时间:

import itertools

def isomorphic_permutations(*arrays, **kwargs):
    arrays_shape = len(arrays[0])
    if any(len(a) != arrays_shape for a in arrays):
        raise ValueError("All input arrays should have the same size.")
    permutations = list(itertools.permutations(range(arrays_shape), **kwargs))
    for array in arrays:
        yield ((array[x], array[y]) for x, y in permutations)

kwarg r用于通过itertools.permutations(iterable, r=None)建立排列。这对应于排列长度。这是使用此功能的方法:

a = [7,6,8]
b = [6,7,8]
for permutation in isomorphic_permutations(a, b, r=2):
    print(list(permutation))

哪个会输出:

[(7, 6), (7, 8), (6, 7), (6, 8), (8, 7), (8, 6)]
[(6, 7), (6, 8), (7, 6), (7, 8), (8, 6), (8, 7)]

请注意,如何根据输出排列重新执行67的反转。

答案 4 :(得分:0)

我没有看到它的建议,但是您不能通过一次选择两者来解决它。

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

from itertools import combinations

list( combinations(zip(a,b),2))

这将产生:

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

您可以看到它们在列表中匹配。