问题
I try to sum a list of nested elements
e.g, numbers=[1,3,5,6,[7,8]]
should produce sum=30
I wrote the following code :
def nested_sum(L):
sum=0
for i in range(len(L)):
if (len(L[i])>1):
sum=sum+nested_sum(L[i])
else:
sum=sum+L[i]
return sum
The above code gives following error:
object of type 'int' has no len()
I also tried len([L[i]])
, still not working.
Anyone can help? It is Python 3.3
回答1:
You need to use isinstance
to check whether an element is a list or not. Also, you might want to iterate over the actual list, to make things simpler.
def nested_sum(L):
total = 0 # don't use `sum` as a variable name
for i in L:
if isinstance(i, list): # checks if `i` is a list
total += nested_sum(i)
else:
total += i
return total
回答2:
It is generally considered more pythonic to duck type, rather than explicit type checking. Something like this will take any iterable, not just lists:
def nested_sum(a) :
total = 0
for item in a :
try:
total += item
except TypeError:
total += nested_sum(item)
return total
回答3:
A quick recursion that uses a lambda to handle the nested lists:
rec = lambda x: sum(map(rec, x)) if isinstance(x, list) else x
rec
, applied on a list, will return the sum (recursively), on a value, return the value.
result = rec(a)
回答4:
I would sum the flattened list:
def flatten(L):
'''Flattens nested lists or tuples with non-string items'''
for item in L:
try:
for i in flatten(item):
yield i
except TypeError:
yield item
>>> sum(flatten([1,3,5,6,[7,8]]))
30
回答5:
One alternative solution with list comprehension:
>>> sum( sum(x) if isinstance(x, list) else x for x in L )
30
Edit: And for lists with more than two levels(thx @Volatility):
def nested_sum(L):
return sum( nested_sum(x) if isinstance(x, list) else x for x in L )
回答6:
This code also works.
def add_all(t):
total = 0
for i in t:
if type(i) == list: # check whether i is list or not
total = total + add_all(i)
else:
total += i
return total
回答7:
An example using filter and map and recursion:
def islist(x):
return isinstance(x, list)
def notlist(x):
return not isinstance(x, list)
def nested_sum(seq):
return sum(filter(notlist, seq)) + map(nested_sum, filter(islist, seq))
And here is an example using reduce and recursion
from functools import reduce
def nested_sum(seq):
return reduce(lambda a,b: a+(nested_sum(b) if isinstance(b, list) else b), seq)
An example using plain old recursion:
def nested_sum(seq):
if isinstance(seq[0], list):
head = nested_sum(seq[0])
else:
head = seq[0]
return head + nested_sum(seq[1:])
An example using simulated recursion:
def nested_sum(seq):
stack = []
stack.append(seq)
result = 0
while stack:
item = stack.pop()
if isinstance(item, list):
for e in item:
stack.append(e)
else:
result += item
return result
Adjustment for handling self-referential lists is left as an exercise for the reader.
回答8:
def nnl(nl): # non nested list function
nn = []
for x in nl:
if type(x) == type(5):
nn.append(x)
if type(x) == type([]):
n = nnl(x)
for y in n:
nn.append(y)
return sum(nn)
print(nnl([[9, 4, 5], [3, 8,[5]], 6])) # output:[9,4,5,3,8,5,6]
a = sum(nnl([[9, 4, 5], [3, 8,[5]], 6]))
print (a) # output: 40
回答9:
A simple solution would be to use nested loops.
def nested_sum(t):
sum=0
for i in t:
if isinstance(i, list):
for j in i:
sum +=j
else:
sum += i
return sum
来源:https://stackoverflow.com/questions/14917092/sum-of-nested-list-in-python