所以我想知道如何最好地创建一个空白列表列表:
[[],[],[]...]
由于Python如何使用内存中的列表,这不起作用:
[[]]*n
这会创建[[],[],...]
,但每个元素都是相同的列表:
d = [[]]*n
d[0].append(1)
#[[1],[1],...]
像列表理解这样的东西:
d = [[] for x in xrange(0,n)]
但这会使用Python VM进行循环。有没有办法使用隐含循环(利用它用C语言编写)?
d = []
map(lambda n: d.append([]),xrange(0,10))
这实际上比较慢。 :(
答案 0 :(得分:86)
可能只是比
快一点的方法d = [[] for x in xrange(n)]
是
from itertools import repeat
d = [[] for i in repeat(None, n)]
它不必在每次迭代中创建一个新的int
对象,并且在我的机器上快5%。
编辑:使用NumPy,您可以使用
来避免Python循环d = numpy.empty((n, 0)).tolist()
但这实际上比列表理解慢2.5倍。
答案 1 :(得分:12)
列表推导实际上比显式循环更有效地实现(参见the dis
output for example functions),并且map
方法必须在每次迭代时调用ophaque可调用对象,这会产生相当大的开销。
无论如何,[[] for _dummy in xrange(n)]
是正确的方法,并且的各种其他方式之间的微小(如果存在)速度差异都不应该重要。当然,除非您花费大部分时间来做这件事 - 但在这种情况下,您应该使用算法。你多久创建一次这些列表?
答案 2 :(得分:10)
以下是两种方法,一种是甜的和简单的(和概念的),另一种是更正式的,可以在阅读数据集之后在各种情况下进行扩展。
方法1:概念
X2=[]
X1=[1,2,3]
X2.append(X1)
X3=[4,5,6]
X2.append(X3)
X2 thus has [[1,2,3],[4,5,6]] ie a list of lists.
方法2:正式和可扩展的
将列表存储为不同数字列表列表的另一种优雅方式 - 它从文件中读取。 (此处的文件包含数据集列表) Train是一个数据集,例如50行和20列。即。 Train [0]给我第一行的csv文件,train [1]给我第二行,依此类推。我有兴趣将数据集与50行分离为一个列表,除了列0,这是我在这里解释的变量,因此必须从orignal train数据集中删除,然后在列表后按比例放大列表 - 即列表列表。这是执行此操作的代码。
请注意,我在内循环中读取“1”,因为我只对解释变量感兴趣。我在另一个循环中重新初始化X1 = [],否则X2.append([0:(len(train [0]) - 1)])会一遍又一遍地重写X1 - 除了它更有效的内存。
X2=[]
for j in range(0,len(train)):
X1=[]
for k in range(1,len(train[0])):
txt2=train[j][k]
X1.append(txt2)
X2.append(X1[0:(len(train[0])-1)])
答案 3 :(得分:1)
所以我做了一些速度比较以获得最快的方式。 列表推导确实非常快。接近的唯一方法是避免在构造列表期间字节码被执行。 我的第一次尝试是以下方法,原则上似乎更快:
l = [[]]
for _ in range(n): l.extend(map(list,l))
(产生一个长度为2 ** n的列表,当然) 根据timeit,对于短期和长期(百万)列表,这种构造的速度是列表理解的两倍。
我的第二次尝试是使用starmap为我调用列表构造函数,有一个构造,它似乎以最高速度运行列表构造函数,但仍然较慢,但只是很少量:
from itertools import starmap
l = list(starmap(list,[()]*(1<<n)))
有趣的是,执行时间表明最终的列表调用使得starmap解决方案变慢,因为它的执行时间几乎完全等于以下的速度:
l = list([] for _ in range(1<<n))
当我意识到列表(())也产生了一个列表时,我的第三次尝试就来了,所以我尝试了这个简单明了:
l = list(map(list, [()]*(1<<n)))
但这比星图呼叫慢。
结论:对于速度疯子: 请使用列表理解。 如果必须,只调用函数。 使用内置。