Python 中列表推导中的多个语句?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/774876/
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-11-03 20:50:19  来源:igfitidea点击:

Multiple statements in list compherensions in Python?

pythonlist-comprehension

提问by Joan Venge

Is it possible to have something like:

是否有可能有类似的东西:

list1 = ...

currentValue = 0
list2 = [currentValue += i, i for i in list1]

I tried that but didn't work? What's the proper syntax to write those?

我试过了,但没有用?写这些的正确语法是什么?

EDIT: the print statement was an example. Actually I am incrementing a value outside the loop.

编辑:打印语句是一个例子。实际上我是在循环外增加一个值。

回答by Brandon Rhodes

Statements cannotgo inside of expressions in Python; it was a complication that was deliberately designed out of the language. For this problem, try using a complication that didmake it into the language: generators. Watch:

语句不能进入 Python 中的表达式;这是一种故意从语言中设计出来的复杂功能。对于这个问题,请尝试使用一种在语言中确实存在的复杂性:生成器。手表:

def total_and_item(sequence):
    total = 0
    for i in sequence:
        total += i
        yield (total, i)

list2 = list(total_and_item(list1))

The generator keeps a running tally of the items seen so far, and prefixes it to each item, just like it looks like you example tries to do. Of course, a straightforward loop might be even simpler, that creates an empty list at the top and just calls append() a lot! :-)

生成器保持到目前为止看到的项目的运行记录,并将其作为每个项目的前缀,就像您的示例试图做的那样。当然,一个简单的循环可能更简单,它在顶部创建一个空列表并且只调用 append() 很多次!:-)

回答by David Z

I'm not quite sure what you're trying to do but it's probably something like

我不太确定你想要做什么,但它可能是这样的

list2 = [(i, i*2, i) for i in list1]
print list2

The statement in the list comprehension has to be a single statement, but you could always make it a function call:

列表推导式中的语句必须是单个语句,但您始终可以将其设为函数调用:

def foo(i):
    print i
    print i * 2
    return i
list2 = [foo(i) for i in list1]

回答by Charlie Martin

Here's an example from another question:

这是另一个问题的示例:

[i for i,x in enumerate(testlist) if x == 1]

the enumerate generator returns a 2-tuple which goes into i,x.

枚举生成器返回一个进入 i,x 的 2 元组。

回答by Manu

As pjz said, you can use functions, so here you can use a closure to keep track of the counter value:

正如 pjz 所说,你可以使用函数,所以在这里你可以使用闭包来跟踪计数器值:

# defines a closure to enclose the sum variable
def make_counter(init_value=0):
    sum = [init_value]
    def inc(x=0):
        sum[0] += x
        return sum[0]
    return inc

Then you do what you want with list1:

然后你用 list1 做你想做的事:

list1 = range(5)  # list1 = [0, 1, 2, 3, 4]

And now with just two lines, we get list2:

现在只有两行,我们得到了 list2:

counter = make_counter(10)  # counter with initial value of 10
list2 = reduce(operator.add, ([counter(x), x] for x in list1))

In the end, list2 contains:

最后,list2 包含:

[10, 0, 11, 1, 13, 2, 16, 3, 20, 4]

which is what you wanted, and you can get the value of the counter after the loop with one call:

这就是您想要的,您可以通过一次调用在循环后获取计数器的值:

counter()  # value is 20

Finally, you can replace the closure stuff by any kind of operation you want, here we have an increment, but it's really up to you. Note also that we use a reduce to flatten list2, and this little trick requires you to import operatorbefore calling the line with the reduce:

最后,你可以用你想要的任何类型的操作替换闭包的东西,这里我们有一个增量,但这真的取决于你。还要注意,我们使用reduce来扁平化list2,这个小技巧需要你在调用带有reduce的行之前导入操作符

import operator

回答by ojrac

Print is a weird thing to call in a list comprehension. It'd help if you showed us what output you want, not just the code that doesn't work.

在列表理解中调用打印是一件很奇怪的事情。如果您向我们展示了您想要的输出,而不仅仅是不起作用的代码,那将会有所帮助。

Here are two guesses for you. Either way, the important point is that the value statement in a list comprehension has to be a singlevalue. You can't insert multiple items all at once. (If that's what you're trying to do, skip to the 2nd example.)

这里有两个猜测给你。无论哪种方式,重要的一点是列表推导式中的值语句必须是单个值。您不能一次插入多个项目。(如果这就是您想要做的,请跳到第二个示例。)

list1 = [1, 2, 3]
list2 = [(i, i*2, i) for i in list1]
# list2 = [(1, 2, 1), (2, 4, 2), (3, 6, 3)]

To get a flat list:

要获得一个平面列表:

list1 = [1, 2, 3]
tmp = [(i, i*2) for i in list1]
list2 = []
map(list2.extend, tmp)
# list2 = [1, 2, 1, 2, 4, 2, 3, 6, 3]

Edit: Incrementing a value in the middle of the list comprehension is still weird. If you really need to do it, you're better off just writing a regular for loop, and appending values as you go. In Python, cleverness like that is almost always branded as "unpythonic." Do it if you must, but you will get no end of flak in forums like this. ;)

编辑:在列表理解的中间增加一个值仍然很奇怪。如果你真的需要这样做,你最好只编写一个常规的 for 循环,并在你进行时附加值。在 Python 中,像这样的聪明几乎总是被贴上“非 Pythonic”的标签。如果必须,请执行此操作,但是在这样的论坛中,您将无休无止。;)

回答by phihag

First of all, you likely don't want to use print. It doesn't return anything, so use a conventional forloop if you just want to print out stuff. What you are looking for is:

首先,您可能不想使用print. 它不返回任何内容,因此for如果您只想打印内容,请使用传统循环。您正在寻找的是:

>>> list1 = (1,2,3,4)
>>> list2 = [(i, i*2) for i in list1] # Notice the braces around both items
>>> print(list2)
[(1, 2), (2, 4), (3, 6), (4, 8)]

回答by John Fouhy

For your edited example:

对于您编辑的示例:

currentValue += sum(list1)

or:

或者:

for x in list1:
    currentValue += x

List comprehensions are great, I love them, but there's nothing wrong with the humble forloop and you shouldn't be afraid to use it :-)

列表推导很棒,我喜欢它们,但是简陋的for循环没有任何问题,您不应该害怕使用它:-)

EDIT: "But what if I wanna increment different than the collected values?"

编辑:“但是如果我想增加与收集的值不同的值怎么办?”

Well, what do you want to increment by? You have the entire power of python at your command!

那么,你想增加多少?您可以随意使用 python 的全部功能!

Increment by x-squared?

按 x 平方递增?

for x in list1:
    currentValue += x**2

Increment by some function of x and its position in the list?

通过 x 的某个函数及其在列表中的位置递增?

for i, x in enumerate(list1):
    currentValue += i*x

回答by Matt

Why would you create a duplicate list. It seems like all that list comprehension would do is just sum the contents.

为什么要创建重复列表。似乎列表理解所做的只是总结内容。

Why not just.

为什么不只是。

list2 = list(list1)   #this makes a copy
currentValue = sum(list2)

回答by pjz

You can't do multiple statements, but you can do a function call. To do what you seem to want above, you could do:

您不能执行多个语句,但可以执行函数调用。要执行上面您似乎想要的操作,您可以执行以下操作:

list1 = ...
list2 = [ (sum(list1[:i], i) for i in list1 ]

in general, since list comprehensions are part of the 'functional' part of python, you're restricted to... functions. Other folks have suggested that you could write your own functions if necessary, and that's also a valid suggestion.

通常,由于列表推导式是 Python 的“功能”部分的一部分,因此您只能使用...函数。其他人建议您可以在必要时编写自己的函数,这也是一个有效的建议。