2010-01-30 54 views
5

我有一个列表L = [A,B,C]我想生成元组的列表:名单乘法

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

我试图做大号* L,但没有奏效。有人能告诉我如何在python中获得这个。

+0

这种“产品”也被称为“笛卡尔产品”或“直接产品”(我不确定一个术语或另一个术语在这里更合适,但Python文档本身使用“笛卡尔产品”。) – MatrixFrog 2010-01-31 05:20:53

回答

13

itertools模块包含了许多有用的功能这样的事情。它看起来像你可能会寻找product

>>> import itertools 
>>> L = [1,2,3] 
>>> itertools.product(L,L) 
<itertools.product object at 0x83788> 
>>> list(_) 
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] 
7

查看itertools模块,该模块提供了一个product成员。

L =[1,2,3] 

import itertools 
res = list(itertools.product(L,L)) 
print(res) 

给出:

[(1,1),(1,2),(1,3),(2,1), .... and so on] 
22

你可以用一个列表理解做到这一点:

[ (x,y) for x in L for y in L] 

编辑

您还可以使用itertools.product像其他人那样建议,但只有当你使用2.6以上。列表理解将适用于2.0版本的所有Python版本。如果你确实使用itertools.product,请记住它会返回一个生成器而不是一个列表,所以你可能需要将它转换(取决于你想用它做什么)。

+0

感谢您的澄清。 – Schitti 2010-01-30 23:23:19

0

X = [A,B,C] Y = [] 为沿x项: 为ITEM2在X: y.append((项目,ITEM2))

也许不是Python化方式但工作

0

确定我尝试:

L2 = [(X,Y)对于x以L为在长x],并将该得到大号正方形。

这是做这件事最好的pythonic方法吗?我希望L * L在Python中工作。

+0

错误的期望 - 'sequence * sequence'是** not **定义的(只有'sequence * int',它做了一些非常不同的事情)。 – 2010-01-30 23:12:31

+0

糟糕,在我看到答案之前写了这个。请忽略 – Schitti 2010-01-30 23:12:50

3

两个主要备选方案:

>>> L = ['a', 'b', 'c'] 
>>> import itertools 
>>> list(itertools.product(L, L)) 
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')] 
>>> [(one, two) for one in L for two in L] 
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')] 
>>> 

前者需要Python 2.6或更高 - 在几乎任何Python版本,后者的作品,你可能会绑。

+0

如果你只是直接转换为列表,使用itertools似乎很奇怪。列表理解可能更有效,就像可读性更强,可能更易于维护,因为可以直接对表达式进行调整。更多的抽象可能意味着更多的僵化,并且整个观点是隐藏你希望的细节(但不能确定),你再也不需要担心了。 – Steve314 2010-01-31 02:14:58

0

最老式的方式做到这一点是:

def perm(L): 
    result = [] 
    for i in L: 
     for j in L: 
      result.append((i,j)) 
    return result 

这为O的运行时间(N^2),因此是相当缓慢的,但你可以认为这是“复古”风格码。

+0

所有的方法都有O(n^2)运行时间,因为它们都必须生成O(n^2)元组。使用诸如itertools之类的迭代器可以让你推迟一些工作,但是你无法完全避免它。你的方法甚至可能是O(n^3) - 由于内存重新分配问题,附加到列表可能是O(n)而不是O(1),尽管我不太清楚。我*认为* Python列表使用可调整大小的数组 - 不是*链接列表。不过,可能会有某种附加优化。列表理解*可能*在开始时预分配整个数组。 – Steve314 2010-01-31 02:03:56