Es gibt viele Möglichkeiten, ein Python-Programm zu schreiben, das ein Histogramm berechnet.Python-Histogramm Einstrich
Mit Histogramm meine ich eine Funktion, die das Auftreten von Objekten in einem iterable
zählt und die Zählungen in einem Wörterbuch ausgibt. Zum Beispiel:
>>> L = 'abracadabra'
>>> histogram(L)
{'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r': 2}
Eine Möglichkeit, diese Funktion zu schreiben ist:
def histogram(L):
d = {}
for x in L:
if x in d:
d[x] += 1
else:
d[x] = 1
return d
Gibt es prägnante Möglichkeiten, diese Funktion zu schreiben?
Wenn wir Wörterbuch Comprehensions in Python hätten, könnten wir schreiben:
>>> { x: L.count(x) for x in set(L) }
aber da Python 2.6 ist sie nicht haben, haben wir schreiben:
>>> dict([(x, L.count(x)) for x in set(L)])
Obwohl dieser Ansatz sein kann, lesbar, es ist nicht effizient: L wird mehrfach durchlaufen. Darüber hinaus wird dies nicht für Single-Life-Generatoren funktionieren; die Funktion sollte für Iterator Generatoren wie gleich gut funktionieren:
def gen(L):
for x in L:
yield x
Wir könnten versuchen, die reduce
Funktion (RIP) zu verwenden:
>>> reduce(lambda d,x: dict(d, x=d.get(x,0)+1), L, {}) # wrong!
Hoppla, das nicht funktioniert: der Schlüssel Name ist 'x'
, nicht x
. :(
I endete mit:
>>> reduce(lambda d,x: dict(d.items() + [(x, d.get(x, 0)+1)]), L, {})
(In Python 3, würden wir list(d.items())
statt d.items()
zu schreiben, aber es ist hypothethical, da es keine reduce
da ist.)
Bitte schlagen ich mit einem besseren, besser lesbaren One-Liner!;)
"Ein Liner" und "lesbarer" schließen sich nicht gegenseitig aus, aber sie sind nahe – msw
Keine Antwort, nur einige Kommentare: Zuerst dict ((x, L.count (x)) für x im Satz (L)) funktioniert sehr gut (zumindest in 2.6 oder so, möglicherweise auch frühere Versionen), so dass es nicht notwendig ist, die Extraliste in Ihrem obigen Beispiel einzuführen. Zweitens, wenn Sie sich nicht für Einzeiler interessieren, dann ist dies ein Job, der für das defaultdict aus dem Collections-Modul maßgeschneidert ist. Ersetzen Sie d = {} durch d = collections.defaultdict (int) in Ihrer ursprünglichen Histogrammfunktion, und dann können Sie das if x in d: Bit überspringen. –
Peter Milley: yor fast dict Verständnis funktioniert sogar in Python 2.5.2! danke, ich war mir dieser syntax nicht bewusst – mykhal