2010-12-13 59 views
2

Je commence juste avec Python et j'en sais assez pour savoir que je ne sais rien. Je voudrais trouver d'autres façons de diviser une liste en une liste de dicts. Exemple Liste:Python: diviser la liste dans le tableau

data = ['**adjective:**', 'nice', 'kind', 'fine', 
     '**noun:**', 'benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal', 
     '**adverb:**', 'well', 'nicely', 'fine', 'right', 'okay'] 

je serais en mesure d'obtenir:

[{'**adjective**': ('nice', 'kind', 'fine'), 
'**noun**': ('benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal'), 
'**adverb**': ('well', 'nicely', 'fine', 'right', 'okay')}] 
+0

Il n'est pas possible d'obtenir une structure liste/dict similaire à celle que vous avez affichée. Il faudrait que ce soit plus comme ceci: '{'adjectif': ['gentil', 'gentil', 'bien'], 'nom': ['bénéfice', 'profit', 'avantage', 'avail', «bien-être», «utiliser», «weal»], «adverbe»: «bien», «bien», «bien», «juste», «ok»]} ' –

+0

Les listes sont ce que la plupart des langages appellent des tableaux, ce que PHP Les tableaux d'appels sont des tableaux et dict combinés. Il n'y a rien de tel que {{key1: val1, val2, val3} 'dans Python. – delnan

+0

Votre sortie n'est pas tout à fait valide. Aimeriez-vous {'adjectif': ['gentil', 'gentil'], 'nom': ['bénéfice', profit ', ...]}? – kevpie

Répondre

10

Cela pourrait être aussi près qu'il arrive à ce que vous avez demandé:

d = collections.defaultdict(list) 
for s in data: 
    if s.endswith(":"): 
     key = s[:-1] 
    else: 
     d[key].append(s) 
print d 
# defaultdict(<type 'list'>, 
#  {'adjective': ['nice', 'kind', 'fine'], 
#  'noun': ['benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal'], 
#  'adverb': ['well', 'nicely', 'fine', 'right', 'okay']}) 

Edit: Juste pour le plaisir un deux-liner alternatif inspiré par la réponse par SilentGhost:

g = (list(v) for k, v in itertools.groupby(data, lambda x: x.endswith(':'))) 
d = dict((k[-1].rstrip(":"), v) for k, v in itertools.izip(g, g)) 
5
>>> data = ['adjective:', 'nice', 'kind', 'fine', 'noun:', 'benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal', 'adverb:', 'well', 'nicely', 'fine', 'right', 'okay'] 
>>> from itertools import groupby 
>>> dic = {} 
>>> for i, j in groupby(data, key=lambda x: x.endswith(':')): 
    if i: 
     key = next(j).rstrip(':') 
     continue 
    dic[key] = list(j) 

>>> dic 
{'adjective': ['nice', 'kind', 'fine'], 'noun': ['benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal'], 'adverb': ['well', 'nicely', 'fine', 'right', 'okay']} 
+0

+1 pour le groupepar –

+0

+1 yup. @SilentGhost, key = next (j) .rstrip (':')? – kevpie

+0

yups ... ne devrait pas être rstrip .... –

0

Si vous assumez intérieure à la liste des mots que vous pourriez avoir ce que le code

data = ['adjective:', 'nice', 'kind', 'fine', 'noun:', 'benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal', 'adverb:', 'well', 'nicely', 'fine', 'right', 'okay'] 

dict = {} 

for x in data: 

    if x[-1] == ':' : 

     start = x.rstrip(':') 

     dict[start] = [] 

    else: 

     dict[start].append(x) 

print dict 

Imprime le dictionnaire suivant

{'adjective': ['nice', 'kind', 'fine'], 'noun': ['benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal'], 'adverb': ['well', 'nicely', 'fine', 'right', 'okay']} 
1

Le code ci-dessous vous donnera un dictionnaire avec un entrée pour chaque mot avec un deux-points après.

data = ['adjective:', 'nice', 'kind', 'fine', 'noun:', 'benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal', 'adverb:', 'well', 'nicely', 'fine', 'right', 'okay'] 
result = {} 
key = None 
for item in data: 
if item.endswith(":"): 
    key = item[:-1] 
    result[key] = [] 
    continue 
result[key].append(item) 
0

Et s'il y avait des clés sans éléments d'une liste après eux? , J'ai pensé. J'ai donc ajouté 'nada:' devant, 'rien:' au milieu, et 'oops:' à la fin de la liste nommée data.

Alors, dans ces conditions, le code 1 (en suivant) avec Groupy semble donner un résultat tout à fait faux, le code 2 avec defaultdict donnent un résultat dans lequel les touches « nada: », « rien: », et 'oups:' sont absents. Ils sont aussi moins rapides que la solution la plus simple (code 3: Cameron, user506710)

J'ai eu une idée => codes 4 et 5. Les résultats sont corrects et les exécutions sont plus rapides.

from time import clock 

data = ['nada:', # <<<============= 
    'adjective:', 
    'nice', 'kind', 'fine', 
    'noun:', 
    'benefit', 'profit', 'advantage', 'avail', 'welfare', 'use', 'weal', 
    'nothing:', # <<<============= 
    'adverb:', 
    'well', 'nicely', 'fine', 'right', 'okay', 
    'oops:'  # <<<============= 
    ] 

#------------------------------------------------------------ 
from itertools import groupby 

te = clock() 
dic1 = {} 
for i, j in groupby(data, key=lambda x: x.endswith(':')): 
    if i: 
     key = next(j).rstrip(':') 
     continue 
    dic1[key] = list(j) 
print clock()-te,' groupby' 
print dic1,'\n' 

#------------------------------------------------------------ 
from collections import defaultdict 
te = clock() 
dic2 = defaultdict(list) 
for s in data: 
    if s.endswith(":"): 
     key = s[:-1] 
    else: 
     dic2[key].append(s) 
print clock()-te,' defaultdict' 
print dic2,'\n\n===================' 

#============================================================= 
te = clock() 
dic4 = {} 
for x in data: 
    if x[-1] == ':' : 
     start = x.rstrip(':') 
     dic4[start] = [] 
    else: 
    dic4[start].append(x) 
print clock() - te 
print dic4,'\n' 

#------------------------------------------------------------ 
te = clock() 
dic3 = {} 
der = len(data) 
for i,y in enumerate(data[::-1]): 
    if y[-1]==':': 
     dic3[y[0:-1]] = data[len(data)-i:der] 
     der = len(data)-i-1 
print clock()-te 
print dic3,'\n' 

    #------------------------------------------------------------ 
te = clock() 
dic5 = {} 
der = len(data) 
for i in xrange(der-1,-1,-1): 
    if data[i][-1]==':': 
     dic5[data[i][0:-1]] = data[i+1:der] 
     der = i 
print clock() - te 
print dic5 

print '\ndic3==dic4==dic5 is',dic3==dic4==dic5