两个列表的笛卡尔积可以 return 除了涉及两个相同元素的组合之外的所有组合吗?

Can Cartesian product of two lists return all the combinations except the combinations involving two same elements?

例如

nested = [a,b,c]

上面列表的笛卡尔积本身将生成以下对

[(a,a),(a,b),(a,c),(b,a),(b,c),(b,b),(c,a),(c,b),(c,c)]

我想找到一种生成以下内容的方法

[(a,b),(a,c),(b,a),(b,c),(c,a),(c,b)]

我尝试了以下方法

[(x,y) for x in nested for y in nested if x != y]

以上代码对于以下测试用例失败

nested_testcase1 = [[1,2],[2,3],[1,2]]

现在上面这行代码会给出如下结果

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

但是我下面的是什么

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

最后两个组合由第一个和最后一个元素配对而成。

有人有什么想法吗?

一个简单的更改:使用对象引用,而不是值:

>>> [(x,y) for x in nested for y in nested if id(x) is not id(y)]
[([1, 2], [2, 3]), ([1, 2], [1, 2]), ([2, 3], [1, 2]), ([2, 3], [1, 2]), ([1, 2], [1, 2]), ([1, 2], [2, 3])]

您可以使用索引而不是检查值,例如:

[(x, y) for i, x in enumerate(data) for j, y in enumerate(data) if i != j]

例如:

>>> [(x, y) for i, x in enumerate(data) for j, y in enumerate(data) if i != j]
[('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]
>>> data = [[1,2],[2,3],[1,2]]
>>> [(x, y) for i, x in enumerate(data) for j, y in enumerate(data) if i != j]
[([1, 2], [2, 3]), ([1, 2], [1, 2]), ([2, 3], [1, 2]), ([2, 3], [1, 2]), ([1, 2], [1, 2]), ([1, 2], [2, 3])]

尝试使用 itertools 排列

import itertools
list(itertools.permutations(['a','b','c'], r=2))

输出随心所欲

[('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]

这也适用于您的情况:

list(itertools.permutations([[1,2],[2,3],[1,2]], 2))

输出为

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

参考看这里: https://docs.python.org/3.7/library/itertools.html#itertools.permutations