能否在列表推导式中返回两个列表?显然下面的写法不起作用,但是是否有类似以下的解决方案:
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)
创建两个 comprehension 列表更好(至少对于长列表而言)。需要注意的是,即使 最佳答案的投票次数最多,它的速度可能还不如传统的 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(*)
更好。 - Reedinationeriterator/generator
和zip
)。但是,差异可以归因于内部计算(代码)。 - toto_tico如果列表元素是列表,那么列表推导式可以返回多个列表。
例如:
>>> x, y = [[] for x in range(2)]
>>> x
[]
>>> y
[]
>>>
zip
函数的技巧可以完成任务,但如果您只是使用循环将结果收集到列表中,实际上会更简单和易读。
range(2)
,因为只有这样你才会得到正好两个空列表。 - Tim Pietzcker
*
运算符。请参考这里。 - LarsVegas*
将列表推导式解包为zip
的参数。您可以查找“列表解包”以获取更多信息。 - jamylaktype(rr)
和type(tt)
是tuple
。OP 要求两个列表。 - Confounded