python列表理解在一次迭代中产生两个值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16594904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:06:42  来源:igfitidea点击:

python list comprehension to produce two values in one iteration

pythonlistlist-comprehension

提问by user1629366

I want to generate a list in python as follows -

我想在 python 中生成一个列表如下 -

[1, 1, 2, 4, 3, 9, 4, 16, 5, 25 .....]

You would have figured out, it is nothing but n, n*n

你会发现,这不过是 n, n*n

I tried writing such a list comprehension in python as follows -

我尝试在 python 中编写这样的列表理解如下 -

lst_gen = [i, i*i for i in range(1, 10)]

But doing this, gives a syntax error.

但是这样做会产生语法错误。

What would be a good way to generate the above list via list comprehension?

通过列表理解生成上述列表的好方法是什么?

采纳答案by Ashwini Chaudhary

Use itertools.chain.from_iterable:

使用itertools.chain.from_iterable

>>> from itertools import chain
>>> list(chain.from_iterable((i, i**2) for i in xrange(1, 6)))
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25]

Or you can also use a generatorfunction:

或者您也可以使用生成器函数:

>>> def solve(n):
...     for i in xrange(1,n+1):
...         yield i
...         yield i**2

>>> list(solve(5))
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25]

回答by Joran Beasley

lst_gen = sum([(i, i*i) for i in range(1, 10)],())

oh I should mention the sum probably breaks the one iteration rule :(

哦,我应该提到总和可能打破了一次迭代规则:(

回答by Martijn Pieters

List comprehensions generate oneelement at a time. Your options are, instead, to change your loop to only generate one value at a time:

列表推导式一次生成一个元素。相反,您的选择是将循环更改为一次仅生成一个值:

[(i//2)**2 if i % 2 else i//2 for i in range(2, 20)]

or to produce tuples then flatten the list using itertools.chain.from_iterable():

或生成元组然后使用itertools.chain.from_iterable()以下方法展平列表:

from itertools import chain

list(chain.from_iterable((i, i*i) for i in range(1, 10)))

Output:

输出:

>>> [(i//2)**2 if i % 2 else i//2 for i in range(2, 20)]
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81]
>>> list(chain.from_iterable((i, i*i) for i in range(1, 10)))
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81]

回答by Matthew Plourde

Another option:

另外一个选项:

reduce(lambda x,y: x + [y, y*y], range(1,10), [])

回答by iruvar

Another option, might seem perverse to some

另一种选择,对某些人来说可能看起来不正常

>>> from itertools import izip, tee
>>> g = xrange(1, 11)
>>> x, y = tee(g)
>>> y = (i**2 for i in y)
>>> z = izip(x, y)
>>> output = []
>>> for k in z:
...     output.extend(k)
... 
>>> print output
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81, 10, 100]

回答by John Hall

You can create a list of lists then use reduce to join them.

您可以创建一个列表列表,然后使用 reduce 来加入它们。

print [[n,n*n] for n in range (10)]

[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]

[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [ 8, 64], [9, 81]]

print reduce(lambda x1,x2:x1+x2,[[n,n*n] for n in range (10)])

[0, 0, 1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81]

[0, 0, 1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81]

 print reduce(lambda x1,x2:x1+x2,[[n**e for e in range(1,4)]\
 for n in range (1,10)])

[1, 1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64, 5, 25, 125, 6, 36, 216, 7, 49, 343, 8, 64, 512, 9, 81, 729]

[1, 1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64, 5, 25, 125, 6, 36, 216, 7, 49, 343, 8, 64, 512, 9 , 81, 729]

Reduce takes a callable expression that takes two arguments and processes a sequence by starting with the first two items. The result of the last expression is then used as the first item in subsequent calls. In this case each list is added one after another to the first list in the list of lists and then that list is returned as a result.

Reduce 接受一个带有两个参数的可调用表达式,并从前两项开始处理序列。然后将最后一个表达式的结果用作后续调用中的第一项。在这种情况下,每个列表都被一个接一个地添加到列表列表中的第一个列表,然后该列表作为结果返回。

List comprehensions implicitly call map with a lambda expression using the variable and sequence defined by the "forvar insequence" expression. The following is the same sort of thing.

列表推导式使用“ forvar insequence”表达式定义的变量和序列隐式调用带有 lambda 表达式的 map 。下面是同样的事情。

map(lambda n:[n,n*n],range(1,10))

[[1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]

[[1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [ 9, 81]]

I am unaware of a more natural python expression for reduce.

我不知道有更自然的 Python 表达式用于 reduce。

回答by Supriya K

>>> lst_gen = [[i, i*i] for i in range(1, 10)]
>>> 
>>> lst_gen
[[1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
>>> 
>>> [num for elem in lst_gen for num in elem]
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81]

Here is my reference http://docs.python.org/2/tutorial/datastructures.html

这是我的参考 http://docs.python.org/2/tutorial/datastructures.html

回答by ytpillai

Try this two liner

试试这两个班轮

lst = [[i, i*i] for i in range(10)]
[lst.extend(i) for i in lst]

Change math as necessary.

根据需要更改数学。

EVEN BETTER

更好

#Change my_range to be the number you want range() function of
start = 1
my_range = 10
lst = [i/2 if i % 2 == 0 else ((i-1)/2)**2 for i in range(start *2, my_range*2 - 1)]

回答by ntg

As mentioned, itertoolsis the way to go. Here's how I would do it, I find it more clear:

如前所述,itertools是要走的路。这是我将如何做到的,我发现它更清楚:

[i if turn else i*i for i,turn in itertools.product(range(1,10), [True, False])]

回答by Yann

The question is old, but just for the curious reader, i propose another possibility: As stated on first post, you can easily make a couple (i, i**2) from a list of numbers. Then you want to flatten this couple. So just add the flatten operation in your comprehension.

这个问题很老,但只是为了好奇的读者,我提出了另一种可能性:如第一篇文章所述,您可以轻松地从数字列表中创建一对 (i, i**2)。然后你想压平这对夫妇。因此,只需在您的理解中添加 flatten 操作即可。

[x for i in range(1, 10) for x in (i,i**2)]