计算两个没有相同索引元素的列表的笛卡尔积
Compute cartesian product of two lists without elements at same index
我有两个长度相同的列表,比如说 3。
A=[1,2,3]
B=[4,5,6]
我想得到两者的笛卡尔积,但是不应该计算相同位置的元素,即:
(1,5),(1,6),(2,4),(2,6),(3,4),(3,5)
我该怎么做?
只要通过正常方式获取产品,然后筛选出来:
import itertools
A=[1,2,3]
B=[4,5,6]
prod = ((x,y) for x,y in itertools.product(A, B) if A.index(x) != B.index(y))
结果:
>>> for p in prod:
... print(p)
...
(1, 5)
(1, 6)
(2, 4)
(2, 6)
(3, 4)
(3, 5)
prod
是一个生成器,所以如果您打算多次使用它,请记住使用 prod = [...]
创建一个理解。
请注意,如果 A
和 B
包含重复元素,这将不起作用。要解决这个问题,enumerate
它并丢弃带有不需要索引的项目:
prod = (item for idx,item in enumerate((x,y) for x,y in itertools.product(A, B)) if idx%(len(A)))
结果:
>>> for p in prod:
... print(p)
...
(1, 5)
(1, 6)
(2, 5)
(2, 6)
(3, 5)
(3, 6)
您几乎可以直接记下您的 'refined' 笛卡尔积:
((a[i], b[j])
for i in range(len(a))
for j in range(len(b))
if i != j)
所以我的方法是使用 zip()
and itertools.product()
:
import itertools
A = [1, 2, 3]
B = [4, 5, 6]
spe = set(zip(A, B))
l = [i for i in itertools.product(A, B) if i not in spe]
来自itertools.product()
的文档:
itertools.product(*iterables, repeat=1)
Cartesian product of input iterables.
Equivalent to nested for-loops in a generator expression. For example, product(A, B)
returns the same as ((x,y) for x in A for y in B)
.
The nested loops cycle like an odometer with the rightmost element advancing on every iteration. This pattern creates a lexicographic ordering so that if the input’s iterables are sorted, the product tuples are emitted in sorted order.
并且 zip()
确实 创建一个迭代器来聚合来自每个可迭代对象的元素。 如文档所述。
所以我的代码创建了一个集合,其中包含您不需要的元素,然后 itertools.product(A, B)
生成完整列表,if i not in spe
删除您不需要的元素列表。
没有对列表进行任何索引,也没有任何基于列表长度的计算,使用普通枚举
>>> g=((a,b) for pa,a in enumerate(A) for pb,b in enumerate(B) if pa!=pb)
>>> for t in g: print(t)
...
(1, 5)
(1, 6)
(2, 4)
(2, 6)
(3, 4)
(3, 5)
您可以为 list A
的每个值迭代 list A
和迭代 list B
。如果两个列表的索引不同,您可以打印出两个列表中元素的组合。
for i in range(len(A)):
for j in range(len(B)):
if i != j:
print '(',A[i],B[j],')'
( 1 5 )
( 1 6 )
( 2 4 )
( 2 6 )
( 3 4 )
( 3 5 )
您可以尝试以下方法。由于笛卡尔积是一个集合,我将以一组元组的形式提供我的答案:
使用集合理解
>>> A=[1,2,3]
>>> B=[4,5,6]
>>> {(a, b) for i, a in enumerate(A) for j, b in enumerate(B) if i != j}
{(1, 5), (1, 6), (2, 4), (2, 6), (3, 4), (3, 5)}
我使用 enumerate(l)
以便在每次迭代时都有一个元组 (index, element)
,其中 index
是 l
的每个 element
的索引。
使用 itertools
>>> import itertools
>>> {(a, b) for a, b in itertools.product(A, B) if A.index(a) != B.index(b)}
{(1, 5), (1, 6), (2, 4), (2, 6), (3, 4), (3, 5)}
我有两个长度相同的列表,比如说 3。
A=[1,2,3]
B=[4,5,6]
我想得到两者的笛卡尔积,但是不应该计算相同位置的元素,即:
(1,5),(1,6),(2,4),(2,6),(3,4),(3,5)
我该怎么做?
只要通过正常方式获取产品,然后筛选出来:
import itertools
A=[1,2,3]
B=[4,5,6]
prod = ((x,y) for x,y in itertools.product(A, B) if A.index(x) != B.index(y))
结果:
>>> for p in prod:
... print(p)
...
(1, 5)
(1, 6)
(2, 4)
(2, 6)
(3, 4)
(3, 5)
prod
是一个生成器,所以如果您打算多次使用它,请记住使用 prod = [...]
创建一个理解。
请注意,如果 A
和 B
包含重复元素,这将不起作用。要解决这个问题,enumerate
它并丢弃带有不需要索引的项目:
prod = (item for idx,item in enumerate((x,y) for x,y in itertools.product(A, B)) if idx%(len(A)))
结果:
>>> for p in prod:
... print(p)
...
(1, 5)
(1, 6)
(2, 5)
(2, 6)
(3, 5)
(3, 6)
您几乎可以直接记下您的 'refined' 笛卡尔积:
((a[i], b[j])
for i in range(len(a))
for j in range(len(b))
if i != j)
所以我的方法是使用 zip()
and itertools.product()
:
import itertools
A = [1, 2, 3]
B = [4, 5, 6]
spe = set(zip(A, B))
l = [i for i in itertools.product(A, B) if i not in spe]
来自itertools.product()
的文档:
itertools.product(*iterables, repeat=1)
Cartesian product of input iterables.Equivalent to nested for-loops in a generator expression. For example,
product(A, B)
returns the same as((x,y) for x in A for y in B)
.The nested loops cycle like an odometer with the rightmost element advancing on every iteration. This pattern creates a lexicographic ordering so that if the input’s iterables are sorted, the product tuples are emitted in sorted order.
并且 zip()
确实 创建一个迭代器来聚合来自每个可迭代对象的元素。 如文档所述。
所以我的代码创建了一个集合,其中包含您不需要的元素,然后 itertools.product(A, B)
生成完整列表,if i not in spe
删除您不需要的元素列表。
没有对列表进行任何索引,也没有任何基于列表长度的计算,使用普通枚举
>>> g=((a,b) for pa,a in enumerate(A) for pb,b in enumerate(B) if pa!=pb)
>>> for t in g: print(t)
...
(1, 5)
(1, 6)
(2, 4)
(2, 6)
(3, 4)
(3, 5)
您可以为 list A
的每个值迭代 list A
和迭代 list B
。如果两个列表的索引不同,您可以打印出两个列表中元素的组合。
for i in range(len(A)):
for j in range(len(B)):
if i != j:
print '(',A[i],B[j],')'
( 1 5 )
( 1 6 )
( 2 4 )
( 2 6 )
( 3 4 )
( 3 5 )
您可以尝试以下方法。由于笛卡尔积是一个集合,我将以一组元组的形式提供我的答案:
使用集合理解
>>> A=[1,2,3]
>>> B=[4,5,6]
>>> {(a, b) for i, a in enumerate(A) for j, b in enumerate(B) if i != j}
{(1, 5), (1, 6), (2, 4), (2, 6), (3, 4), (3, 5)}
我使用 enumerate(l)
以便在每次迭代时都有一个元组 (index, element)
,其中 index
是 l
的每个 element
的索引。
使用 itertools
>>> import itertools
>>> {(a, b) for a, b in itertools.product(A, B) if A.index(a) != B.index(b)}
{(1, 5), (1, 6), (2, 4), (2, 6), (3, 4), (3, 5)}