【发布时间】:2012-05-07 08:59:33
【问题描述】:
是否可以从列表推导中返回两个列表?好吧,这显然行不通,但是类似于:
rr, tt = [i*10, i*12 for i in xrange(4)]
所以rr 和tt 都是列表,结果分别来自i*10 和i*12。
非常感谢
【问题讨论】:
是否可以从列表推导中返回两个列表?好吧,这显然行不通,但是类似于:
rr, tt = [i*10, i*12 for i in xrange(4)]
所以rr 和tt 都是列表,结果分别来自i*10 和i*12。
非常感谢
【问题讨论】:
>>> rr,tt = zip(*[(i*10, i*12) for i in xrange(4)])
>>> rr
(0, 10, 20, 30)
>>> tt
(0, 12, 24, 36)
【讨论】:
* 运算符。看看 [这里] :(docs.python.org/library/functions.html#zip)
* 将列表推导解包为 zip 的参数。您可以查看“列表解包”以获取更多信息。
创建两个推导式列表更好(至少对于长列表)。请注意,最佳投票答案较慢可能比传统的 for 循环还要慢。 列表理解更快更清晰。
python -m timeit -n 100 -s 'rr=[];tt = [];' 'for i in range(500000): rr.append(i*10);tt.append(i*12)'
10 loops, best of 3: 123 msec per loop
> python -m timeit -n 100 'rr,tt = zip(*[(i*10, i*12) for i in range(500000)])'
10 loops, best of 3: 170 msec per loop
> python -m timeit -n 100 'rr = [i*10 for i in range(500000)]; tt = [i*10 for i in range(500000)]'
10 loops, best of 3: 68.5 msec per loop
很高兴看到列表推导支持一次创建多个列表。
如果您可以利用传统循环(准确地说是中间计算),那么您可能会更好地使用循环(或使用yield 的iterator/generator)。这是一个例子:
$ python3 -m timeit -n 100 -s 'rr=[];tt=[];' "for i in (range(1000) for x in range(10000)): tmp = list(i); rr.append(min(tmp));tt.append(max(tmp))"
100 loops, best of 3: 314 msec per loop
$ python3 -m timeit -n 100 "rr=[min(list(i)) for i in (range(1000) for x in range(10000))];tt=[max(list(i)) for i in (range(1000) for x in range(10000))]"
100 loops, best of 3: 413 msec per loop
当然,这些案例的比较是不公平的;在该示例中,代码和计算并不等效,因为在传统循环中存储了一个临时结果(请参阅tmp 变量)。因此,列表推导式执行了更多的内部操作(它计算了两次 tmp 变量!但它只慢了 25%)。
【讨论】:
return x, y 的函数,希望将所有x 保留在一个列表中,而将所有y 保留在另一个列表中。在这种情况下进行两次推导会不必要地加倍时间复杂度,因为您在第一次推导中丢弃了 y(计算成本很高)......只是为了再次重新计算它们并这次丢弃 x。在这种情况下,我认为zip(*) 更好。
如果元素是列表,列表推导可能会返回多个列表。 比如:
>>> x, y = [[] for x in range(2)]
>>> x
[]
>>> y
[]
>>>
zip 函数的诀窍可以完成这项工作,但如果您只是通过循环将结果收集到列表中,实际上会更加简单和易读。
【讨论】:
range(2),因为只有这样你才能得到两个列表。然后是空列表。