说我们有一个清单:
X = [1,2,3,4,5,6,7,8]
我们创建了一个名为add()的函数:
def add():
sum = 0
result = 0
for e in X:
sum = sum + e
return sum
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]
为什么我在此列表中获得NoneType值?
答案 0 :(得分:4)
您可以使用yield
执行此操作以保持原始格式:
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)
是的,可以在列表推导中调用函数。你的例子很好 - 这是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])]
结果是前缀总和列表 - 你想要的东西。
答案 2 :(得分:2)
你的方法不起作用,因为你的add()
是无国籍的。您需要在add()
的不同调用之间维护状态的内容,否则add()
将始终生成相同的输出。
实现目标的一个解决方案是itertools.accumulate()
。有关讨论,请参阅Equivalent of Haskell scanl in python。
此处的其他答案建议使用涉及range()
的列表理解。虽然这可行,但它也是低效的,因为O(n ^ 2)算法从头开始重新计算每个条目的累积和。
答案 3 :(得分:0)
#!/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]
答案 4 :(得分:0)
是的,可以在列表理解中调用任何函数。
另请注意,在Python 2.x中,由于print
is not a function(在Python 2中),因此无法在列表推导中使用print
。
对于您的示例 - 它可能看起来像这样,使用add()
函数使用共享状态(s
变量):
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]
如果没有该共享状态,请参阅其他答案,以便在忘记设置s = 0
时不会得到不同的结果。