views:

101

answers:

5

Is there a way to see how many items in a dictionary share the same value in Python?

Let's say that I have a dictionary like:

{"a": 600, "b": 75, "c": 75, "d": 90}

I'd like to get a resulting dictionary like:

{600: 1, 75: 2, 90: 1}

My first naive attempt would be to just use a nested-for loop and for each value then I would iterate over the dictionary again. Is there a better way to do this?

+1  A: 
>>> a = {"a": 600, "b": 75, "c": 75, "d": 90}
>>> b = {}
>>> for k,v in a.iteritems():
...     b[v] = b.get(v,0) + 1
...
>>> b
{600: 1, 90: 1, 75: 2}
>>>
MattH
+5  A: 

You could use itertools.groupby for this.

import itertools
x = {"a": 600, "b": 75, "c": 75, "d": 90}
[(k, len(list(v))) for k, v in itertools.groupby(x.values())]
WoLpH
Worked for me! Thanks WoLpH, but I had to adjust it to use a dictionary instead: {k: len(list(v)) for k, v in itertools.groupby(x.values())}
Jared
Won't work in the general case without **sorting** those values! E.g. with the `sorted` Python built-in function.
Alex Martelli
A: 

Use Counter (2.7+, see below at link for implementations for older versions) along with dict.values().

Ignacio Vazquez-Abrams
+2  A: 

When Python 2.7 comes out you can use its collections.Counter class

otherwise see counter receipe

Under Python 2.7a3

from collections import Counter
items = {"a": 600, "b": 75, "c": 75, "d": 90}    
c = Counter( items )

print(  dict( c.items() ) )

output is

{600: 1, 90: 1, 75: 2}

Mark
py 3.1 is already out and there is no need to repost exactly the same answer few times a day.
SilentGhost
@SilentGhost, Py 3.1 is out, but 2.7 isn't (still alpha) -- and as long as people post questions obviously requiring Counter it's perfectly fine to point them to it!
Alex Martelli
@Alex: it's a duplicate of a duplicate that had duplicate answer given in each thread by the same user. rather than multiplying entities it's better close the question altogether.
SilentGhost
If this question's a duplicate, why are there _zero_ votes to close it? Attacking the _answer_ is weird, especially when you haven't even given one "vote to close" for the question (and neither has anybody else, I note!-).
Alex Martelli
A: 
>>> a = {"a": 600, "b": 75, "c": 75, "d": 90}
>>> d={}
>>> for v in a.values():
...   if not v in d: d[v]=1
...   else: d[v]+=1
...
>>> d
{600: 1, 90: 1, 75: 2}
ghostdog74