Reputation: 335
Here is a small piece of Python code to add elements of a nested list:
def nested_sum(lists):
s = [0,0,0,0,0,0,0,0] # If I delete this line then an error is given
for i in range(len(lists)):
s[i] = sum(lists[i])
print sum(s)
lists = [[1],[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6] ]
nested_sum(lists)
Please excuse the formatting.
Issue with this code lies in the line I have commented.
The error shown was:
NameError: global name 's' is not defined
How can I avoid this error without declaring the list s
before?
Upvotes: 0
Views: 400
Reputation: 25043
You don't need any intermediate list (and no extra memory, as per the comment by Lol4t0)
def nested_sum(lists):
print sum(sum(l) for l in lists)
the syntax I've used is a generator expression.
Of course it is much more flexible to declare your function w/o the print
,
def nested_sum(lists):
return sum(sum(l) for l in lists)
and then use it like this
l = [[1],[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6] ]
print nested_sum(l)
Upvotes: 1
Reputation: 93
There is a shorter and more pythonic way of doing that:
>>> lists = [[2,4], [1]]
>>> [sum(x) for x in lists]
output: [6, 1]
You can read further on list comprehensions
Upvotes: 0
Reputation: 78750
If you delete the marked line you get a NameError
because you try to index into something (s
) before defining what that name should refer to. That should be clear.
The easiest way to solve your problem in one go is to us a generator expression in conjunction with sum
with or without the chain
function from itertools
(depending on your preference).
Without chain
:
>>> lists = [[1],[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6] ]
>>> sum(value for sublist in lists for value in sublist)
56
With chain
:
>>> from itertools import chain
>>> sum(chain(*lists))
56
which is equivalent to
>>> sum(chain.from_iterable(lists))
56
Upvotes: 3
Reputation: 79
Another way to do this would be to use a variable to store the sum rather than a list and use the 'in' keyword to iterate through the list items rather than a range:
def nested_sum(lists):
list_sum = 0
for i in lists:
list_sum += sum(i)
print (list_sum)
lists = [[1],[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6] ]
nested_sum(lists)
Upvotes: 1
Reputation: 15320
Specifically in your case you don't actually need s
to achieve the same functionality (if you don't mind altering the contents of lists
):
def nested_sum(lists):
for i in range(len(lists)):
lists[i] = sum(lists[i])
print sum(lists)
>>> lists = [[1],[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6] ]
>>> nested_sum(lists)
56
Upvotes: 1
Reputation: 3891
You could convert your for loop to a oneliner so you don't have to pre-declare the variable s
. Here is the code:
def nested_sum(lists):
s = [sum(lists[i]) for i in range(len(lists))] #converted for loop to oneliner
print sum(s)
lists = [[1],[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6] ]
nested_sum(lists)
Upvotes: 2
Reputation: 986
In this case, you always have to declare list. But you can choose how. For example:
1) s = [0] * len(lists)
- will be equal to your declaration
2) s = []
, next you do something like this:
for i in range(len(lists)):
s.append(sum(lists[i]))
Upvotes: 1