单个python列表理解中的两个赋值

时间:2012-06-21 22:43:00

标签: python list-comprehension

例如:

a = [1,2,3]
x = [2*i for i in a]
y = [3*i for i in a]

如果a的大小很大,将列表推导组合成一个(如果可能的话)会更有效吗?如果是这样,你怎么做?

类似的东西,

x,y = [2*i, 3*i for i in a]

哪个不起作用。如果使用列表推导在计算效率上不比使用普通for循环更高效,请告诉我。感谢。

2 个答案:

答案 0 :(得分:12)

您希望将the zip() builtin与星号运算符一起使用来执行此操作。 zip()通常会将列表转换为对列表,如果像这样使用,它会解压缩 - 获取对列表并拆分成两个列表。

>>> a = [1, 2, 3]
>>> x, y = zip(*[(2*i, 3*i) for i in a])
>>> x
(2, 4, 6)
>>> y
(3, 6, 9)

请注意,我不确定这是否会以一种重要的方式提高效率。

答案 1 :(得分:9)

如果对效率有疑问,请使用timeit模块,它总是很容易使用:

import timeit

def f1(aRange):
    x = [2*i for i in aRange]
    y = [3*i for i in aRange]
    return x,y

def f2(aRange):
    x, y = zip(*[(2*i, 3*i) for i in aRange])
    return x,y

def f3(aRange):
    x, y = zip(*((2*i, 3*i) for i in aRange))
    return x,y

def f4(aRange):
    x = []
    y = []
    for i in aRange:
        x.append(i*2)
        y.append(i*3)
    return x,y

print "f1: %f" %timeit.Timer("f1(range(100))", "from __main__ import f1").timeit(100000)
print "f2: %f" %timeit.Timer("f2(range(100))", "from __main__ import f2").timeit(100000)
print "f3: %f" %timeit.Timer("f3(range(100))", "from __main__ import f3").timeit(100000)
print "f4: %f" %timeit.Timer("f4(range(100))", "from __main__ import f4").timeit(100000)

结果似乎与指向第一个选项最为一致。

f1: 2.127573
f2: 3.551838
f3: 3.859768
f4: 4.282406