2010-01-19 3 views
1

Une liste d'exemple des listes:Catégoriser une liste de listes par 1 élément en python

[ 
["url","name","date","category"] 
["hello","world","2010","one category"] 
["foo","bar","2010","another category"] 
["asdfasdf","adfasdf","2010","one category"] 
["qwer","req","2010","another category"] 
] 

Ce que je veux faire est de créer un dictionnaire -> catégorie: [liste des entrées].

Le dictionnaire résultant serait:

{"category" : [["url","name","date","category"]], 
"one category" : [["hello","world","2010","one category"],["asdfasdf","adfasdf","2010","one category"]], 
"another category" : [["foo","bar","2010","another category"], ["qwer","req","2010","another category"]]} 

Répondre

7
dict((category, list(l)) for category, l 
    in itertools.groupby(l, operator.itemgetter(3)) 

La chose principale est ici l'utilisation de itertools.groupby. Il retourne simplement iterables au lieu de listes, ce qui explique pourquoi il y a un appel à list(l), ce qui signifie que si vous êtes ok avec cela, vous pouvez simplement écrire dict(itertools.groupby(l, operator.itemgetter(3)))

+1

Vous pouvez utiliser 'operator.itemgetter (3)' à la place de lambda. –

+0

@Ignacio - tu as raison, j'oublie toujours celui-là. – abyx

+1

Je ne sais jamais si ces doublures qui utilisent itertools/lambdas/whatnot sont meilleures que les versions plus verbeuses/explicites. Pour quelqu'un qui lit ceci sans voir un exemple de ce qui se passe, c'est très difficile à comprendre. –

5
newdict = collections.defaultdict(list) 
for entry in biglist: 
    newdict[entry[3]].append(entry) 
+0

newdict ['catégorie qui n'existe pas'] ajoute un nouvel élément à newdict. Cela pourrait être bien avec l'affiche originale, mais c'est une sémantique très spécifique. – EOL

+1

@EOL: Il ne prend que les catégories qui sont dans la liste d'origine, donc je ne vois pas de problème ici. –

+0

En général, il n'y a aucune raison pour que newdict ['category that not existing'] soit défini sur [] lorsque 'category that no exists' n'est pas dans la liste. Par exemple, l'existence de certaines catégories pourrait être testée avec 'try: newdict ['example category'] sauf KeyError: ...' Si newdict est un collections.defaultdict, aucune exception ne sera levée, alors qu'un dict déclenchera une exception. Je voulais juste donner un avertissement: collections.defaultdicts ne se comportent pas exactement comme des dicts, et l'affiche originale voulait un dict. – EOL

1
list_of_lists=[ 
["url","name","date","category"], 
["hello","world","2010","one category"], 
["foo","bar","2010","another category"], 
["asdfasdf","adfasdf","2010","one category"], 
["qwer","req","2010","another category"] 
] 
d={} 
for li in list_of_lists: 
    d.setdefault(li[-1], []) 
    d[ li[-1] ].append(li) 
for i,j in d.iteritems(): 
    print i,j 
+1

+1, mais voir ma réponse, qui utilise le fait que setdefault() renvoie une valeur. – EOL

1

d = {} 
for e in l: 
    if e[3] in d: 
     d[e[3]].append(e) 
    else: 
     d[e[3]] = [e] 
+0

gens vraiment donnot comme simple ... –

+0

oublie la liste est non-lavable ... –

+0

Quel est le problème avec cela? C'est simple, et ça fonctionne. L [0] [3] est "catégorie", et ainsi de suite. – telliott99

-2
>>> l = [ 
... ["url","name","date","category"], 
... ["hello","world","2010","one category"], 
... ["foo","bar","2010","another category"], 
... ["asdfasdf","adfasdf","2010","one category"], 
... ["qwer","req","2010","another category"], 
... ] 
#Intermediate list to generate a more dictionary oriented data 
>>> dl = [ (li[3],li[:3]) for li in l ] 
>>> dl 
[('category', ['url', 'name', 'date']), 
('one category', ['hello', 'world', '2010']), 
('another category', ['foo', 'bar', '2010']), 
('one category', ['asdfasdf', 'adfasdf', '2010']), 
('another category', ['qwer', 'req', '2010'])] 
#Final dictionary 
>>> d = {} 
>>> for cat, data in dl: 
... if cat in d: 
...  d[cat] = d[cat] + [ data ] 
... else: 
...  d[cat] = [ data ] 
... 
>>> d 
{'category': [['url', 'name', 'date']], 
'one category': [['hello', 'world', '2010'], ['asdfasdf', 'adfasdf', '2010']], 
'another category': [['foo', 'bar', '2010'], ['qwer', 'req', '2010']]} 

Le données finales c'est un peu différent car je n'ai pas inclus sur les données la catégorie (me semble tout à fait inutile), mais vous pouvez l'ajouter facilement, si nécessaire ...

2

Une variation sur la réponse de ghostdog74, qui complète y utilise la sémantique de setdefaults:

result={} 
for li in list_of_lists: 
    result.setdefault(li[-1], []).append(li) 
Questions connexes