11

I have a dictionary that looks like:

G={'E': 18.0, 'D': 17.0, 'C': 19.0, 'B': 15.0, 'A': 0}

I have to find the mean of the values e.g. mean(18,17,19,15,0) using a simple for loop without using built in functions like .values(), .items() and so on. I tried the following but am getting an error:

d=[float(sum(values)) / len(values) for key, values in G]
    return (d)   
ValueError: need more than 1 value to unpack

Can someone help me fix this????

FlorianH
  • 600
  • 7
  • 18
Rachel
  • 383
  • 2
  • 4
  • 13

10 Answers10

16

If you use numpy:

import numpy as np

np.array(list(dict.values())).mean()
Sergio R
  • 161
  • 1
  • 3
12

To do this with a "simple for loop", using your constraints against using the dict methods:

G = {'E': 18.0, 'D': 17.0, 'C': 19.0, 'B': 15.0, 'A': 0}


count = 0
_sum = 0
for key in G:
    count += 1
    _sum += G[key]

print('this is the mean: ', _sum/count)

If you're supposed to avoid dict methods, clearly this is an academic exercise.

Without that constraint:

The statistics module in the standard library has a mean method, which would be my first thought (as the standard library does not require third party packages.):

>>> G={'E': 18.0, 'D': 17.0, 'C': 19.0, 'B': 15.0, 'A': 0}
>>> from statistics import mean
>>> mean(G[k] for k in G)
13.8

Third party packages like numpy and pandas have objects with a mean method:

>>> from numpy import array
>>> array([G[k] for k in G]).mean()
13.8

>>> from pandas import Series
>>> Series([G[k] for k in G]).mean()
13.8

If we allow ourselves to use the values() method, this gets a little simpler with iterable unpacking. For some reason the other answers violate that condition, so I figure I should show the more efficient way of doing it:

>>> Series([*G.values()]).mean()
13.8
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
12
import numpy as np
np.mean(list(dict.values()))
insanely_sin
  • 986
  • 1
  • 14
  • 22
4

Iteration over a dictionary iterates over its keys. Try just using for key in G, and then using G[key] appropriately instead of values.

Alternatively, use the iteritems() method of the dictionary to get key, value pairs from G, i.e.:

d=[float(sum(values)) / len(values) for key, values in G.iteritems()]

(For the record, your actual method of computing a mean doesn't look right to me, but you may as well fix the iteration problem first).

Gian
  • 13,735
  • 44
  • 51
  • is it possible to use this without inbuilt functions like .iteritems() ? – Rachel Mar 14 '14 at 22:10
  • Sure, you use the first method I suggested where you use `for key in G` rather than `for key, values in G`, and then use `G[key]` to refer to the actual values. – Gian Mar 14 '14 at 22:11
4

In Python 3.4 upwards there is a very clear way:

import statistics
numbers = [G[key] for key in G]
mean_ = statistics.mean(numbers)
barrios
  • 1,104
  • 1
  • 12
  • 21
3

Use G.values() to get all the values from a dictionary.

G = {'E': 18.0, 'D': 17.0, 'C': 19.0, 'B': 15.0, 'A': 0}
d = float(sum(G.values())) / len(G)
print (d)

This prints 13.8.

Note that there is a difference between Python 2 and Python 3 here. In Python 2, G.values() is a newly constructed list of values. In Python 3, it is a generator, which can be thought of as a “lazy list”. The same thing is called G.itervalues() in Python 2.

Gassa
  • 8,546
  • 3
  • 29
  • 49
1

You want:

mean = sum([G[key] for key in G])/float(len(G))

Your original code will also produce a:

TypeError: 'int' object is not iterable

when you try to sum the values.

ebarr
  • 7,704
  • 1
  • 29
  • 40
  • You don't really even need to use the `keys` list here. You can just iterate directly over the keys of `G`, like: `sum([G[key] for key in G])/float(len(G))` – Gian Mar 14 '14 at 22:05
1

What I suggest instead of the current answers is adopting a functional programming paradigm that is reusable and flexible. For example, creating a function to calculate any statistic on list values contained within a simple dict:

def summarize_dict(dictionary, function):
        dict_new = {}
    for k,v in dictionary.items():
        dict_new[k] = function(v)
    return dict_new

Testing:

import numpy as np

keys = ["a","b","c","d","e"]
values = [range(2),range(4),range(6),range(8),range(10)]
dictionary = dict(zip(keys, values))

summarize_dict(dictionary, np.mean)

Yields:

{'a': 0.5, 'b': 1.5, 'c': 2.5, 'd': 3.5, 'e': 4.5}
Adam Erickson
  • 6,027
  • 2
  • 46
  • 33
0

Another for-loop, this one not needing a counter for items.

G = {'E': 18.0, 'D': 17.0, 'C': 19.0, 'B': 15.0, 'A': 0}

sum = 0
for k in G:
    sum += float(G[k])

print "Mean: " + str(sum/len(G))

Results to:

Mean: 13.8
[Finished in 0.3s]

Actually, given your data, there's no need to use float. On my end, removing float and just leaving sum += G[k] still outputs the same since the values are not strings anyway.

WGS
  • 13,969
  • 4
  • 48
  • 51
0

Suppose you have a dictionary with multiple keys, each having a list of values:

your_averaged_dictionary = {key: np.mean(values) for key, values in your_dictionary}
inverted_index
  • 2,329
  • 21
  • 40