Reputation: 7644
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
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
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
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