Reputation: 509
I have a list of lists named allBins
which contains several lists which represent different bins, inside those bins are varying numbers of tuples with the format (iD, volume). I need to iterate through to sum the volumes of the items in each of the bins by summing the second element of the tuples.
I've tried many things:
sum(bin[1] for bin in allBins)
gives me a 'list index out of range' error presumably because some bins have more than one tuple?
allBins = [[(3,20)],[(1,11),(0,6)],[(4,16),(2,5)]]
I need a line of code that, depending on which bin I choose to sum, gives me the following integers:
1st bin: 20
2nd bin: 17
3rd bin: 21
Upvotes: 2
Views: 1602
Reputation: 17824
You can use the following function:
from operator import itemgetter
allBins = [[(3,20)],[(1,11),(0,6)],[(4,16),(2,5)]]
def func(bin_num, all_bins):
bin = itemgetter(bin_num)(all_bins)
s = sum(map(itemgetter(-1), bin))
return s
print(func(2, allBins))
# 21
Upvotes: 0
Reputation: 12983
The problem you have is you want to only sum one bin, but you're trying to sum across all bins. This means when you access the first bin, with the value [(3,20)]
and ask for element with index 1, there is only an element with index 0 and you get the out of bounds error.
You want something like this:
def sum_bin(bin_num, data):
my_bin = data[bin_num]
return sum(t[1] for t in my_bin)
>>> sum_bin(0, allBins)
20
>>> sum_bin(1, allBins)
17
>>> sum_bin(2, allBins)
21
as a "one liner", assuming you have a variable capturing the bin you want
sum(t[1] for t in allBins[bin_idx])
This is called a generator comprehension, and while it's similar to a list comprehension, there are subtle differences.
Upvotes: 2
Reputation: 1010
for c,b in enumerate(allBins):
if c == bin_you_choose_to_sum:
partial=0
for t in b:
partial+=t[1]
print("Bin {}: {}".format(c, partial))
Upvotes: 0
Reputation: 26039
You can use a list-comprehension:
allBins = [[(3,20)],[(1,11),(0,6)],[(4,16),(2,5)]]
print([sum(y[1] for y in x) for x in allBins])
# [20, 17, 21]
Treating your actual requirement: "I need some sort of loop or comprehension that, depending on which bin I choose to sum":
allBins = [[(3,20)],[(1,11),(0,6)],[(4,16),(2,5)]]
bin_number = 2
print(sum(x[1] for x in allBins[bin_number-1]))
# 17
You can specify bin_number
and the above finds sum for that particular bin.
Upvotes: 5
Reputation: 6404
Once iterating over the main list, you can use sum
to add up the integers.
allBins = [[(3,20)],[(1,11),(0,6)],[(4,16),(2,5)]]
def sumup(which, allBins):
return sum(tup[1] for tup in allBins[which])
print(sumup(1, allBins))
Doc: sum built-in
Upvotes: 2
Reputation: 226316
You were close :-) Just put the summing fragment you gave inside a list comprehension so that it runs one summation per bin.
FWIW, you can also use operator.itemgetter() for a beautiful, functional approach:
>>> from operator import itemgetter
>>> allBins = [[(3,20)],[(1,11),(0,6)],[(4,16),(2,5)]]
>>> [sum(map(itemgetter(1), bin)) for bin in allBins]
[20, 17, 21]
Read this as, "make a list of sums for every bin in all bins" where the sums are "sum of item one in each tuple in a bin".
Upvotes: 2