2010-10-30 11 views
3

Liste.Diviser la liste des noms en dictionnaire alphabétique, en Python

['Chrome', 'Chromium', 'Google', 'Python'] 

Résultat.

{'C': ['Chrome', 'Chromium'], 'G': ['Google'], 'P': ['Python']} 

Je peux le faire fonctionner comme ceci.

alphabet = dict() 
for name in ['Chrome', 'Chromium', 'Google', 'Python']: 
    character = name[:1].upper() 
    if not character in alphabet: 
    alphabet[character] = list() 
    alphabet[character].append(name) 

Il est probablement un peu plus rapide pour pré-remplir le dictionnaire avec A-Z, pour enregistrer le contrôle de clé sur chaque nom, puis supprimez ensuite les touches avec des listes vides. Je ne suis pas sûr que ce soit la meilleure solution.

Y a-t-il un pythonic pour ce faire?

Répondre

9

Quelque chose ne va pas avec ça? Je suis d'accord avec Antoine, la solution oneliner est plutôt cryptique.

import collections 

alphabet = collections.defaultdict(list) 
for word in words: 
    alphabet[word[0].upper()].append(word) 
+0

C'est beaucoup mieux. –

+0

C'est la première chose qui me vient à l'esprit. – aaronasterling

5

Je ne sais pas si c'est Pythonic, mais il est plus succinct:

import itertools 
def keyfunc(x): 
    return x[:1].upper() 
l = ['Chrome', 'Chromium', 'Google', 'Python'] 
l.sort(key=keyfunc) 
dict((key, list(value)) for (key,value) in itertools.groupby(l, keyfunc)) 

EDIT 2 rendu moins succinct que la version précédente, plus lisible et plus correct (groupby fonctionne comme prévu uniquement trié lists)

+0

et c'est elligible pour le concours de code obfusqué –

+2

@Antoine: J'espère que non. Le groupby rend l'intention assez claire. – Amnon

+0

En le rendant correct, vous avez également fait beaucoup moins efficace. Je pourrais à peu près «groupby» et rouler avec une solution à un passage à ce stade. – aaronasterling