Il y a plusieurs façons d'écrire un programme en Python qui calcule un histogramme.
Par histogramme, je veux dire une fonction qui compte le nombre de survenance d'objets dans un iterable
et sorties le compte dans un dictionnaire. Par exemple:
>>> L = 'abracadabra'
>>> histogram(L)
{'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r': 2}
Une façon d'écrire cette fonction est:
def histogram(L):
d = {}
for x in L:
if x in d:
d[x] += 1
else:
d[x] = 1
return d
Il n'y a plus concis façons d'écrire cette fonction?
Si nous avions dictionnaire des inclusions en Python, nous pourrions écrire:
>>> { x: L.count(x) for x in set(L) }
mais depuis la version 2.6 de Python n'en ont pas, nous avons à écrire:
>>> dict([(x, L.count(x)) for x in set(L)])
Bien que cette approche peut être lisible, il n'est pas efficace: L a marche à travers de multiples fois. En outre, cela ne fonctionne pas pour une seule vie, des générateurs de la fonction devrait fonctionner tout aussi bien pour l'itérateur générateurs tels que:
def gen(L):
for x in L:
yield x
Nous pourrions essayer d'utiliser l' reduce
de la fonction (R. I. P.):
>>> reduce(lambda d,x: dict(d, x=d.get(x,0)+1), L, {}) # wrong!
Oups, cela ne fonctionne pas: le nom de la clé est - 'x'
, pas x
. :(
J'ai fini avec:
>>> reduce(lambda d,x: dict(d.items() + [(x, d.get(x, 0)+1)]), L, {})
(En Python 3, il nous faudrait écrire list(d.items())
au lieu de d.items()
, mais c'est hypothethical, car il n'y a pas d' reduce
, là.)
Merci de me battre avec une meilleure, plus lisible one-liner! ;)