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

问题描述 投票:0回答:10

是否可以有这样的东西:

list1 = ...

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

我尝试过但没有成功?编写这些内容的正确语法是什么?

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

python list-comprehension
10个回答
33
投票

语句不能进入Python中的表达式内部;这是一种从语言中故意设计出来的复杂性。对于这个问题,尝试使用 did 使其进入语言的复杂功能:生成器。观看:

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

list2 = list(total_and_item(list1))

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


4
投票

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

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

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

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

3
投票

正如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

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

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

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

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

最后list2包含:

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

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

counter()  # value is 20

最后,您可以用任何您想要的操作来替换闭包内容,这里我们有一个增量,但这实际上取决于您。 另请注意,我们使用reduce来展平list2,这个小技巧要求您在调用带有reduce的行之前导入operator

import operator

2
投票

这是来自另一个问题的示例:

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

枚举生成器返回一个 2 元组,该元组包含在 i,x 中。


1
投票

首先,您可能不想使用

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)]

1
投票

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

这里有两个猜测供您参考。无论哪种方式,重要的一点是列表理解中的值语句必须是“单个”值。您无法一次插入多个项目。 (如果这就是您想要做的,请跳到第二个示例。) list1 = [1, 2, 3] list2 = [(i, i*2, i) for i in list1] # list2 = [(1, 2, 1), (2, 4, 2), (3, 6, 3)]

要获得平面列表:

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]

编辑:
在列表理解的中间增加一个值仍然很奇怪。如果您确实需要这样做,最好只编写一个常规的 for 循环,并在执行过程中附加值。在 Python 中,这样的聪明几乎总是被贴上“非 Python 化”的标签。如果必须的话就这样做,但在这样的论坛上你会受到无休无止的批评。 ;)


1
投票

currentValue += sum(list1)

或:

for x in list1: currentValue += x

列表理解很棒,我喜欢它们,但是简单的 
for

循环没有任何问题,你不应该害怕使用它:-)


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

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

增加 x 平方?

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

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

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



1
投票

为什么不只是。

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



0
投票

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

一般来说,由于列表推导式是 python 的“功能”部分的一部分,因此您只能使用...函数。其他人建议您可以根据需要编写自己的函数,这也是一个有效的建议。


0
投票

[f(x) for x in l] list(map(f, l)) # similar

您当然可以应用返回多个值的函数:

[(x, x+1) for x in l] # a little shorter list(map(lambda x: (x, x+1), l))

© www.soinside.com 2019 - 2024. All rights reserved.