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?

Jared
  • 5,977
  • 10
  • 38
  • 48

5 Answers5

7

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(sorted(x.values()))]
Wolph
  • 78,177
  • 11
  • 137
  • 148
  • 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 Mar 06 '10 at 20:04
  • 4
    Won't work in the general case without **sorting** those values! E.g. with the `sorted` Python built-in function. – Alex Martelli Mar 06 '10 at 23:21
2

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}

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
  • py 3.1 is already out and there is no need to repost exactly the same answer few times a day. – SilentGhost Mar 06 '10 at 20:10
  • 1
    @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 Mar 06 '10 at 23:20
  • 1
    @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 Mar 06 '10 at 23:43
  • 1
    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 Mar 06 '10 at 23:56
1
>>> 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
  • 37,273
  • 11
  • 82
  • 84
0

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

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
0
>>> 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
  • 327,991
  • 56
  • 259
  • 343