两个列表的笛卡尔积可以 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
例如
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