简体   繁体   English

理解:每次迭代多个值

[英]Comprehensions: multiple values per iteration

Is there a way to output two (or more) items per iteration in a list/dictionary/set comprehension? 有没有办法在列表/字典/集合理解中每次迭代输出两个(或更多)项目? As a simple example, to output all the positive and negative doubles of the integers from 1 to 3 (that is to say, {x | x = ±2n, n ∈ {1...3}} ), is there a syntax similar to the following? 作为一个简单的例子,输出从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 know I could output tuples of (+i,-i) and flatten that, but I was wondering if there was any way to completely solve the problem using a single comprehension. 我知道我可以输出(+i,-i)元组并将其弄平,但我想知道是否有任何方法可以使用单一理解来完全解决问题。

Currently, I am producing two lists and concatenating them (which works, provided the order isn't important): 目前,我正在生成两个列表并将它们连接起来(如果订单不重要,则可以正常工作):

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

Another option is a nested comprehension: 另一种选择是嵌套理解:

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

For a more general case: 对于更一般的情况:

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

with your original example: 用你原来的例子:

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

although I'd really suggest itertools.chain.from_iterable as @Lattyware said. 虽然我真的建议使用@Lattyware的itertools.chain.from_iterable

Another form of nested comprehension: 嵌套理解的另一种形式:

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

The best answer here is to simply use itertools.chain.from_iterable() to, as you mention, flatten the list: 这里最好的答案是简单地使用itertools.chain.from_iterable() ,如你所述,展平列表:

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

This is pretty readable, and doesn't require iterating over the source twice (which may be problematic given some iterators can be exhausted, and it means extra computational effort). 这是非常易读的,并且不需要两次迭代源(这可能是有问题的,因为一些迭代器可能会耗尽,这意味着额外的计算工作量)。

Although I would use the itertools method @Lattyware suggested, here is a more general approach using a generator that may also be helpful. 虽然我会使用@Lattyware建议的itertools方法,但这是一种使用生成器的更通用的方法,也可能有用。

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


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

According to PEP202 there is no way to output more than one object from a list comprehension: 根据PEP202 ,无法从列表推导中输出多个对象:

- The form [x, y for ...] is disallowed; - 不允许使用[x, y for ...]的形式; one is required to write [(x, y) for ...] . 一个人需要写[(x, y) for ...]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM