2009-11-05 5 views
0

Je viens de lire dans un fichier qui est quelque chose comme:Listes de tri de la liste des dictionnaires

name: john, jane 
car: db9, m5 
food: pizza, lasagne 

Chacune de ces lignes (noms, voiture, nourriture) sont en ordre de qui possède quoi. Par conséquent, John possède la voiture «DB9» et sa nourriture préférée est «Pizza». De même qu'avec Jane, sa voiture est un 'M5' et sa nourriture préférée est 'Lasagne'.

J'ai efficacement:

>>> names['Name']="John" 
>>> namesL.append(name) 
>>> names['Name']="Jane" 
>>> namesL.append(name) 
>>> car['Car']="DB9" 
>>> cars.append(car) 
>>> car['Car']="M5" 
>>> cars.append(car) 
>>> food['Food']="Pizza" 
>>> foodL.append(food) 
>>> food['Food']="Lasagne" 
>>> foodL.append(food) 

>>>ultimateList.append(foodL) 
...  

Cependant je veux pour que chacune de ces choses sont dans leur propre dictionnaire. Donc, quelque chose comme ceci:

>>>PersonalDict 
{'Name': 'John', 'Car': 'DB9', 'Food': 'Pizza'} 

J'ai fixais pendant un certain temps et ne peut pas travailler comment j'aborder ce sujet. Quelqu'un peut-il offrir quelques idées ou dois-je faire cela d'une autre manière?

Répondre

3

On dirait que vous voulez quelque chose comme:

import collections 

data = '''name: john, jane 
car: db9, m5 
food: pizza, lasagne 
''' 

personal_list = collections.defaultdict(dict) 

for line in data.splitlines(): 
    key, _, info = line.partition(':') 
    infos = info.split(',') 
    key = key.strip().title() 
    for i, item in enumerate(infos): 
    item = item.strip().title() 
    personal_list[i][key] = item 

for i in personal_list: 
    print personal_list[i] 

qui ne fait pas exactement ce que vous spécifiez (la capitalisation du B dans DB9 semble tout à fait bizarre par exemple - - comment le code sait-il capitaliser cette deuxième lettre particulière et pas n'importe quelle autre seconde lettre?!) mais il semble assez proche.

+0

Je suis un peu confus. Comment incluriez-vous la lecture dans le fichier avec ceci? – Federer

+0

Pour lire un fichier, utilisez 'for line dans f.readlines()'. Je suis content de voir que la version que j'ai écrite est presque identique à celle d'Alex, sauf que la première ligne de ma boucle for est '(k, _, d) = map (str.title, map (str.strip, line.partition (":"))) ' –

+0

Vous n'avez pas besoin d'utiliser' for line dans f.readlines() 'pour lire un fichier; il suffit de dire 'pour line in f'. La méthode '.readlines()' slurp dans toutes les lignes dans le fichier et faire une liste en mémoire; l'objet fichier renvoyé par 'open()' agira comme un itérateur, produisant une ligne à la fois. – steveha

1

Essayez:

f = open('filename.txt') 

result = [] 
for line in f: 
    key, values = line.split(':') 
    values = values.rstrip().split(', ') 
    for i, value in enumerate(values): 
     try: 
      result[i][key] = value 
     except IndexError: 
      result.append({ key: value}) 

print result 
1

Divisez les données initiales en triplets d'index/clé/valeur à partir de là.

def parse_data(lines): 
    for line in lines: 
     key, _, data = line.partition(':') 
     for i, datum in enumerate(x.strip() for x in data.split(',')): 
      yield i, key, datum 

De là, vous pouvez regrouper les données useing approche de defaultdict d'Alex (probablement le meilleur) ou trier et un tas de code supplémentaire pour construire des dictionnaires individuels sur demande.

1

Un hommage aux générateurs:

#!/usr/bin/env python 
data=(zip(*([elt.strip().title() for elt in line.replace(':',',',1).split(',')] 
      for line in open('filename.txt','r')))) 
personal_list=[dict(zip(data[0],datum)) for datum in data[1:]] 
print(personal_list) 

# [{'Food': 'Pizza', 'Car': 'Db9', 'Name': 'John'}, {'Food': 'Lasagne', 'Car': 'M5', 'Name': 'Jane'}] 

Pour comprendre comment fonctionne le script, nous le briser:

D'abord, nous charger filename.txt dans une liste de lignes:

In [41]: [line for line in open('filename.txt','r')] 
Out[41]: ['name: john, jane\n', 'car: db9, m5\n', 'food: pizza, lasagne\n'] 

Ensuite, nous remplaçons le premier deux-points (:) avec une virgule (,)

In [42]: [line.replace(':',',',1) for line in open('filename.txt','r')] 
Out[42]: ['name, john, jane\n', 'car, db9, m5\n', 'food, pizza, lasagne\n'] 

Ensuite, nous avons divisé chaque ligne sur des virgules:

In [43]: [line.replace(':',',',1).split(',') for line in open('filename.txt','r')] 
Out[43]: 
[['name', ' john', ' jane\n'], 
['car', ' db9', ' m5\n'], 
['food', ' pizza', ' lasagne\n']] 

Pour chaque élément dans chaque ligne, nous Désape début/fin des espaces et capitalisons la chaîne comme un titre:

In [45]: [[elt.strip().title() for elt in line.replace(':',',',1).split(',')] for line in open('filename.txt','r')] 
Out[45]: [['Name', 'John', 'Jane'], ['Car', 'Db9', 'M5'], ['Food', 'Pizza', 'Lasagne']] 

Maintenant, nous recueillons le premier élément de chaque liste, puis la seconde, et ainsi de suite:

In [47]: data=(zip(*([elt.strip().title() for elt in line.replace(':',',',1).split(',')] for line in open('filename.txt','r')))) 

In [48]: data 
Out[48]: [('Name', 'Car', 'Food'), ('John', 'Db9', 'Pizza'), ('Jane', 'M5', 'Lasagne')] 

data [0] occupe maintenant les clés pour un dict.

In [49]: data[0] 
Out[49]: ('Name', 'Car', 'Food') 

Chaque ligne de données [1:] correspond aux valeurs d'une dict.

In [50]: data[1:] 
Out[50]: [('John', 'Db9', 'Pizza'), ('Jane', 'M5', 'Lasagne')] 

Ici, nous zip les clés avec les valeurs:

In [52]: [ zip(data[0],datum) for datum in data[1:]] 
Out[52]: 
[[('Name', 'John'), ('Car', 'Db9'), ('Food', 'Pizza')], 
[('Name', 'Jane'), ('Car', 'M5'), ('Food', 'Lasagne')]] 

Enfin, nous nous tournons dans une liste de dicts:

In [54]: [dict(zip(data[0],datum)) for datum in data[1:]] 
Out[54]: 
[{'Car': 'Db9', 'Food': 'Pizza', 'Name': 'John'}, 
{'Car': 'M5', 'Food': 'Lasagne', 'Name': 'Jane'}] 
+0

+1, mais je ne représenterais jamais quelque chose comme ça dans le code de production. –

Questions connexes