在python中是否可以在列表理解中调用函数(而不是内置函数)?

在python中是否可以在列表理解中调用函数(而不是内置函数)?,python,function,list-comprehension,nested,Python,Function,List Comprehension,Nested,假设我们有一个列表: X = [1,2,3,4,5,6,7,8] 我们创建了一个名为add()的函数: 它运行在一个数字X列表中,将列表中的下一个元素添加到上一个总和。对于每个元素X[i],我们有: 1 3 6 10 15 21 28 36 45 现在,如果我想利用列表理解再次将这些结果放入列表中,该怎么办。是否可以在列表中调用add()之类的函数, 假设可以在列表理解中应用内置函数 我尝试了以下方法: L = [add() for e in X] print L 给 [None, Non

假设我们有一个列表:

X = [1,2,3,4,5,6,7,8]
我们创建了一个名为add()的函数:

它运行在一个数字X列表中,将列表中的下一个元素添加到上一个总和。对于每个元素X[i],我们有:

1
3
6
10
15
21
28
36
45
现在,如果我想利用列表理解再次将这些结果放入列表中,该怎么办。是否可以在列表中调用add()之类的函数, 假设可以在列表理解中应用内置函数

我尝试了以下方法:

L = [add() for e in X]
print L

[None, None, None, None, None, None, None, None, None]
而不是

[1,3,6,10,15,21,28,36,45]

为什么在此列表中获取非类型值?

是的,可以在列表理解中调用函数。您的示例很好-应该归咎于
add()
函数。 您需要的是使
add()
函数接收一个参数-要求和的列表

def add(elements):
    sum = 0
    for el in elements:
        sum += el
    return sum
这样,列表理解将如下所示:

L = [add(X[:i+1]) for i in xrange(len(X))]
[1, 3, 6, 10, 15, 21, 28, 36]
这相当于:

L = [add(X[:1]), add(X[:2]), ..., add(X[:8])]

这是一个前缀和的列表-你想要的东西。

你的方法行不通,因为你的
add()
是无状态的。您需要在不同的
add()
调用之间保持状态的东西,否则
add()
将始终产生相同的输出

实现您想要的目标的一个解决方案是。请参阅以进行讨论


这里的其他答案建议使用包含
范围()
的列表理解。虽然这样做可行,但效率也很低,因为O(n^2)算法从头开始重新计算每个条目的累积总和。

您可以使用
收益率来执行此操作,以保持原始格式:

    X = [1,2,3,4,5,6,7,8]

    def add():
      sum = 0
      for e in X:
        sum = sum + e
        yield sum

    L = [value for value in add()]
    print L
产生以下结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 3, 6, 10, 15, 21, 28, 36, 45]

是的,可以调用列表理解中的任何函数

还要注意,在Python2.x中,列表理解中不能有
print
,因为(在Python2中)

在您的示例中,使用与共享状态一起工作的
add()
函数(
s
变量),它可能看起来像这样:


查看其他答案如何在没有共享状态的情况下执行此操作,以便在忘记设置
s=0

时不会得到不同的结果我不确定单个
add()
调用如何生成多个值。这里有点不对劲-
add()
函数只返回一个值,每次都应该相同(因为没有修改
X
)。您确定在
add()
中有
return
而没有
print
?您的
for
循环在第一次迭代时返回。可能会重复I get
[1,1,1,1,1,1,1]
;您确定使用了正确的
add()
function?
L=[value for value in add()]
在这种情况下似乎更清晰。我还建议将
add()
更改为以
X
为参数。你是说列表X会因此而固定吗?你能澄清一下你在这里的意思吗?我是说每次你调用
add()
,它将产生相同的输出,因为它不需要参数,不执行突变,并且通常是非状态的。克拉斯克的建议是将
返回
改为
产生
,因为生成器确实保持状态。
#!/usr/bin/env python
"""
produce a list that adds each item to the previous item
this list [1,2,3,4] will produce this list [1,3,6,10]
"""

def accumulate(my_list, previous = 0):
    for i in my_list:
        previous += i
        yield previous

x = [1,2,3,4,5,6,7,8,9]
new_list = []
new_list = [i for i in accumulate(x)]
print x   
print new_list
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 3, 6, 10, 15, 21, 28, 36, 45]
s = 0   # better not use name 'sum' as it is already a builtin function
def add(i):
    global s
    s += i
    return s
X = [1, 2, 3, 4, 5, 6, 7, 8]
print [add(i) for i in X]
# prints [1, 3, 6, 10, 15, 21, 28, 36]
# but beware the global shared state! for example when called again:
print [add(i) for i in X]
# prints [37, 39, 42, 46, 51, 57, 64, 72]