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