两个列表的笛卡尔积能否返回除包含两个相同元素的组合之外的所有组合?

2024-06-24 12:15:45 发布

您现在位置:Python中文网/ 问答频道 /正文

例如

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])]

最后两个组合是通过配对第一个和最后一个元素来实现的。你知道吗

有人有什么想法吗?你知道吗


Tags: 方法代码in元素列表forif测试用例
3条回答

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

>>> [(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

相关问题 更多 >