我有两个长度相同的列表,它们具有一对一的对应关系:
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)]
答案 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)]
请注意,如何根据输出排列重新执行6
和7
的反转。
答案 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))]
您可以看到它们在列表中匹配。