Shubham R
Shubham R

Reputation: 7644

Sum values in nested lists python

I have a list:

l = [['a', 10, 30], ['b', 34, 89], ['c', 40, 60],['d',30,20]]

where the first item inside each sublist is the name and other two number are marks (sub1 and sub2)

The nested lists can be dynamic, i.e the number of nested lists can change according to function.

What I am looking for is to find

average of subj 1 i.e (10+34+40+30)/4 and 
similarly sub2 (30+89+60+20)/4

also average marks of a: (10+30)/2
average marks of b: (34+89)/2  and so on.

I tried:

c = 0
for i in range(0,len(list_marks1)):
    c += list_marks1[i][1]
sub_1avg = float(c)/len(list_marks1)
d = 0
for i in range(0,len(list_marks1)):
    d += list_marks1[i][2]
sub_2avg = float(d)/len(list_marks1)

but this is not correct.

Is there any optimal way to do this? Since the number of subjects in my nested lists can also change.

Upvotes: 2

Views: 3542

Answers (3)

MSeifert
MSeifert

Reputation: 152657

You could just use sum and a generator expression:

>>> l= [['a', 10, 30], ['b', 34, 89], ['c', 40, 60],['d',30,20]]
>>> length = float(len(l))  # in Python 3 you don't need the "float"
>>> sum(subl[1] for subl in l) / length 
28.5
>>> sum(subl[2] for subl in l) / length
49.75

Or even do that inside a list comprehension:

>>> [sum(subl[subj] for subl in l) / length for subj in range(1, 3)]
[28.5, 49.75]

Similarly for the average of one sublist:

>>> length = float(len(l[0])) - 1
>>> [sum(subl[1:]) / length for subl in l]
[20.0, 61.5, 50.0, 25.0]

When you have python 3.4 or newer you can replace the sum / length with statistics.mean:

>>> from statistics import mean
>>> [mean(subl[subj] for subl in l) for subj in range(1, 3)]  
[28.5, 49.75]

>>> [mean(subl[1:]) for subl in l]
[20, 61.5, 50, 25]

You asked about the best way so I probably should mention that there are packages dedicated for tabular data. For example If you have pandas it's even easier using DataFrame and mean:

>>> import pandas as pd

>>> df = pd.DataFrame(l, columns=['name', 'x', 'y']) 
>>> df[['x', 'y']].mean(axis=0)
x    28.50
y    49.75
dtype: float64

>>> df[['x', 'y']].mean(axis=1)
0    20.0
1    61.5
2    50.0
3    25.0
dtype: float64

Upvotes: 5

Sanju
Sanju

Reputation: 2194

l= [['a', 10, 30], ['b', 34, 89], ['c', 40, 60],['d',30,20]]
sub1_avg =  sum(n for _,n, _ in l)/float(len(l))
sub2_avg =  sum(n for _,_, n in l)/float(len(l))
student_avgs = [{x[0]: sum(x[1:])//float((len(x)-1))} for x in l]
print "Sub1 avg - {}\nSub2 avg - {}\nstudent avg - {}".format(sub1_avg, sub2_avg, student_avgs)

sample output

Sub1 avg - 28.5
Sub2 avg - 49.75
student avg - [{'a': 20.0}, {'b': 61.0}, {'c': 50.0}, {'d': 25.0}]

Upvotes: 0

Netwave
Netwave

Reputation: 42708

A fucnitonal approach:

l= [['a', 10, 30], ['b', 34, 89], ['c', 40, 60],['d',30,20]]
map(lambda x: sum(x)/float(len(x)), zip(*l)[1:])
[28.5, 49.75]

This way will work for any sublist length

Upvotes: 0

Related Questions