1

I have the following dictionary:

StudentGrades = {
    'Ivan': [4.32, 3, 2],
    'Martin': [3.45, 5, 6],
    'Stoyan': [2, 5.67, 4],
    'Vladimir': [5.63, 4.67, 6]
}

I want to make a function that prints the average of the grades of the students, i.e. the average of the values

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Vladimir Dimov
  • 83
  • 1
  • 1
  • 4
  • Access each key's value, sum it, divide by the number of items, and print the results. – MattDMo Jun 06 '15 at 20:29
  • 1
    Do you know how to loop over the matching keys and values in a dictionary? Do you know how to take an average of a list? Do you know how to print something? Each of these questions has been asked and answered many times on SO. By combining them, you can do what you need to -- and if you're still having a problem, your question can become very specific and concrete. – DSM Jun 06 '15 at 20:31
  • What exactly do you need? Average dictionary value/s or average value of dictionary or average value each value element from the keys ??? – Pralhad Narsinh Sonar Jun 06 '15 at 20:32
  • 1
    1 line dict-comprehension: `{k:np.mean(v) for k, v in StudentGrades.items()}` – kevin_theinfinityfund Sep 09 '22 at 21:44

3 Answers3

14

This answer was intended for Python2, which is now dead

Okay, so let's iterate over all dictionary keys and average the items:

avgDict = {}
for k,v in StudentGrades.iteritems():
    # v is the list of grades for student k
    avgDict[k] = sum(v)/ float(len(v))

In Python3, the iteritems() method is no longer necessary, can use items() directly.

now you can just see :

avgDict
Out[5]: 
{'Ivan': 3.106666666666667,
 'Martin': 4.816666666666666,
 'Stoyan': 3.89,
 'Vladimir': 5.433333333333334}

From your question I think you're queasy about iteration over dicts, so here is the same with output as a list :

avgList = []
for k,v in StudentGrades.iteritems():
    # v is the list of grades for student k
    avgDict.append(sum(v)/ float(len(v)))

Be careful though : the order of items in a dictionary is NOT guaranteed; this is, the order of key/values when printing or iterating on the dictionary is not guaranteed (as dicts are "unsorted"). Looping over the same identical dictionary object(with no additions/removals) twice is guaranteed to behave identically though.

Jiby
  • 1,865
  • 1
  • 13
  • 22
4

If you don't want to do the simple calculation use statistics.mean:

from statistics import mean

StudentGrades = {
    'Ivan': [4.32, 3, 2],
    'Martin': [3.45, 5, 6],
    'Stoyan': [2, 5.67, 4],
    'Vladimir': [5.63, 4.67, 6]
}

for st,vals in StudentGrades.items():
    print("Average for {} is {}".format(st,mean(vals)))
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
0
from scipy import mean
map(lambda x: mean(StudentGrades[x]), StudentGrades)

Generates this output:

[3.1066666666666669,
 3.8900000000000001,
 5.4333333333333336,
 4.8166666666666664]

If you prefer a non-scipy solution one could use sum and len like supposed by Jiby:

map(lambda x: sum(StudentGrades[x])/len(StudentGrades[x]), StudentGrades)

EDIT: I am terribly sorry, I forgot you want a Python 3.4 solution, therefore (because you would get a map object returned) you need, for example, an additional list command:

from scipy import mean
list(map(lambda x: mean(StudentGrades[x]), StudentGrades))

This will return the desired output.

daniel451
  • 10,626
  • 19
  • 67
  • 125
  • 2
    Nice oneliner, but loading scipy for a simple dict ? ^^ – Jiby Jun 06 '15 at 20:30
  • Yeah, loading the whole scipy is maybe not that good if you really just need this one method...but as my edit shows, you could load just mean...I do not think that this would be a problem. – daniel451 Jun 06 '15 at 20:37
  • True ^^. Also : the order of elements depends on how the dictionary is iterated over (which is implementation dependent) – Jiby Jun 06 '15 at 20:37