Re: Modal value of an array



Alex Martelli:
foo = ["spam", "eggs", "spam", "spam", "spam", "beans", "eggs"]
max(foo, key=foo.count)

It's a very nice solution, the shortest too. But I think it's better
to develop your own well tested and efficient stats module (and there
is one already done that can be found around) and import it when you
need functions, instead of using similar onliners or re-writing code.
As you know your solution becomes rather slow if the list is quite
long, and it works with lists only.
This uses more memory but it's probably much faster for longer
interables:

from collections import defaultdict

def mode(seq):
freqs = defaultdict(int)
for el in seq:
freqs[el] += 1
return max(freqs.itervalues())


Generally you may want to know what's the mode element(s) too:

def mode2(seq):
freqs = defaultdict(int)
for el in seq:
freqs[el] += 1
maxfreq = max(freqs.itervalues())
mode_els = [el for el,f in freqs.iteritems() if f == maxfreq]
return maxfreq, mode_els

foo = ["spam", "eggs", "spam", "spam", "spam", "beans", "eggs"]
print mode(foo)
print mode2(foo)

Bye,
bearophile

.



Relevant Pages

  • Re: Break up list into groups
    ... def gengroups0: ... for val in seq: ... usec/pass ... `getgroups3' is a method I got from another post in this thread, ...
    (comp.lang.python)
  • Re: Break up list into groups
    ... def gengroups0: ... for val in seq: ... usec/pass ... Here's a small improvement of getgroups1, ...
    (comp.lang.python)
  • Re: multirember&co
    ... def multiremberandco1b(el, seq, fun): ... yield self.queue.popleft ...
    (comp.lang.python)
  • Re: multirember&co
    ... def multiremberandco4(el, iseq, fun): ... for el in seq: ... So I have tried to create two iterables for the fun function scanning ...
    (comp.lang.python)
  • Re: multirember&co
    ... lists from a given one, at the end it applies the generic given fun ... def multiremberandco1(el, seq, fun): ...
    (comp.lang.python)