理解:每次迭代多个值

时间:2013-03-20 22:21:22

标签: python generator list-comprehension

有没有办法在列表/字典/集合理解中每次迭代输出两个(或更多)项目?举个简单的例子,要输出从1到3的整数的正负双精度(也就是{x | x = ±2n, n ∈ {1...3}}),是否有类似下面的语法?

>>> [2*i, -2*i for i in range(1, 4)]
[2, -2, 4, -4, 6, -6]

我知道我可以输出(+i,-i)的元组并将其弄平,但我想知道是否有任何方法可以使用单一理解来完全解决问题。

目前,我正在制作两个列表并将它们连接起来(如果订单不重要,它可以正常工作):

>>> [2*i for i in range(1, 4)] + [-2*i for i in range(1, 4)]
[2, 4, 6, -2, -4, -6]

5 个答案:

答案 0 :(得分:7)

另一种选择是嵌套理解:

r = [2*i*s for i in range(1, 4) for s in 1, -1]

更一般的情况:

r = [item for tpl in (<something that yields tuples>) for item in tpl]

使用您的原始示例:

r = [item for tpl in ((2*i, -2*i) for i in range(1, 4)) for item in tpl]

虽然我真的建议itertools.chain.from_iterable为@Lattyware说。

答案 1 :(得分:6)

另一种嵌套理解形式:

>>> [sub for i in range(1, 4) for sub in (2*i, -2*i)]
[2, -2, 4, -4, 6, -6]

答案 2 :(得分:4)

这里最好的答案就是如你所说,简单地使用itertools.chain.from_iterable()来压扁列表:

itertools.chain.from_iterable((2*i, -2*i) for i in range(1, 4))

这很可读,并且不需要对源进行两次迭代(这可能会有问题,因为某些迭代器可能会耗尽,这意味着额外的计算工作量。)

答案 3 :(得分:4)

虽然我会使用@Lattyware建议的itertools方法,但这是一种使用生成器的更通用的方法,也可能有用。

>>> def nums():
        for i in range(1, 4):
            yield 2*i
            yield -2*i


>>> list(nums())
[2, -2, 4, -4, 6, -6]

答案 4 :(得分:1)

根据PEP202,无法从列表推导中输出多个对象:

  

- 不允许使用[x, y for ...]表格;一个人需要写         [(x, y) for ...]