Python中的列表推导式如何使用多个语句?

17 投票
10 回答
27185 浏览
提问于 2025-04-15 11:12

有没有可能写成这样:

list1 = ...

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

我试过这样做,但没有成功?正确的写法应该是什么样的呢?

补充说明:我提到的打印语句只是个例子。实际上,我是在循环外面增加一个值。

10 个回答

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
6

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

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

在Python中,语句是不能放在表达式里面的;这是为了避免复杂性而特意设计的。对于这个问题,可以尝试使用一种确实被引入到语言中的复杂性:生成器。来看这个例子:

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

list2 = list(total_and_item(list1))

这个生成器会记录到目前为止看到的所有项目,并把它们加到每个项目的前面,就像你例子中想要做的那样。当然,直接用一个简单的循环可能会更简单,先创建一个空列表,然后多次调用append()方法就可以了!:-)

撰写回答