¿Necesita ayuda de bucle diccionario de Python

No he hecho mucha progtwigción en Python y estoy intentando leer en un csv básico y luego crear un diccionario nested a partir de él. Esto es lo que tengo hasta ahora y parece que tengo algunos problemas con hacer un bucle o sobrescribir mi dictado. Sé que no es muy eficiente.

import csv reader = csv.DictReader(open("fruit.csv")) fruit_dict = {} color_dict = {} for row in reader: info_list = [] count = row.pop('count') info_list.append(count) year = row.pop('year') info_list.append(year) info = row.pop('info') info_list.append(info) if row['color'] not in color_dict: #print row['color'] color_dict['color'] = row['color'] #print fruit_dict if row['fruit'] not in fruit_dict: fruit_dict['name'] = row['fruit'] #print fruit_dict #print info_list list_of_info_lists =[] list_of_info_lists.append(info_list) fruit_dict['fruitInfo'] = list_of_info_lists color_dict['fruit'] = fruit_dict #print color_dict else: list_of_info_lists.append(info_list) fruit_dict['fruitInfo'] = list_of_info_lists color_dict['fruit'] = fruit_dict #print color_dict else: if row['color'] in color_dict: if row['fruit'] not in fruit_dict: fruit_dict['name'] = row['fruit'] #print fruit_dict #print info_list list_of_info_lists =[] list_of_info_lists.append(info_list) fruit_dict['fruitInfo'] = list_of_info_lists color_dict['fruit'] = fruit_dict #print color_dict else: list_of_info_lists.append(info_list) fruit_dict['fruitInfo'] = list_of_info_lists color_dict['fruit'] = fruit_dict #print color_dict #print color_dict 

Aquí está el csv:

 color,fruit,year,count,info red,apple,1970,3,good red,apple,1922,5,okay orange,orange,1935,2,okay green,celery,2001,22,marginal red,cherries,1999,5,outstanding orange,carrot,1952,7,okay green,celery,2014,2,good green,grapes,2001,12,good 

Lo que estoy consiguiendo es esto:

 {'color': 'green', 'fruit': {'name': 'grapes', 'fruitInfo': [['12', '2001', 'good']]}} 

Lo cual es encantador, excepto que estoy esperando unas cuantas líneas más que eso y estoy esperando una lista de listas cuando el ‘nombre’ ya existe, por ejemplo:

 {'color': 'red', 'fruit': {'name': 'apple', 'fruitInfo': [['5', '1922', 'okay'],['3', '1970', 'good']]}} 

Cualquier consejo sería muy apreciado. El objective final es generar un archivo json.

Gracias susan

Aquí está el formato que me gustaría tener al final:

 [{'color': 'red', 'fruit': {'name': 'apple', 'fruitInfo': [['5', '1922', 'okay'],['3', '1970', 'good']]}}, {'color': 'red', 'fruit': {'name': 'cherries', 'fruitInfo': [['5', '1999', 'outstanding']]}}, {'color': 'orange', 'fruit': {'name': 'orange', 'fruitInfo': [['2', '1935', 'okay']]}}, {'color': 'orange', 'fruit': {'name': 'carrot', 'fruitInfo': [['7', '1952', 'okay']]}}, {'color': 'green', 'fruit': {'name': 'celery', 'fruitInfo': [['2', '2014', 'good'],['22', '2001', 'marginal']]}}, {'color': 'green', 'fruit': {'name': 'grapes', 'fruitInfo': [['12', '2001', 'good']]}}] 

Cuando trato con diccionarios de diccionarios, mi patrón es así:

 sub_dict = main_dict.get(key, {}) sub_dict[sub_key] = sub_value main_dict[key] = sub_dict 

Esto obtiene el sub-diccionario, o {} si no existe. A continuación, asigna un valor al sub-diccionario y vuelve a colocar el sub-diccionario en el diccionario principal.

 fruit_dict = {} for row in reader: # make the info_list info_list = [row['count'], row['year'], row['info']] # extract color and fruit into variables color = row['color'] fruit = row['fruit'] # unpack the dictionaries and list colors = fruit_dict.get(color, {}) fruits = colors.get(fruit, {}) info = fruits.get('info', []) # reassemble the list and dictionaries info.append(info_list) fruits['info'] = info colors[fruit] = fruits fruit_dict[color] = colors 

El resultado es un poco diferente a su ejemplo, pero es necesario cambiarlo para usar el color y la fruta como claves.

{‘naranja’: {‘naranja’: {‘información’: [[‘2’, ‘1935’, ‘vale’]]}, ‘zanahoria’: {‘información’: [[‘7’, ‘1952’ , ‘okay’]]}}, ‘green’: {‘apio’: {‘info’: [[’22’, ‘2001’, ‘marginal’], [‘2’, ‘2014’, ‘good’ ]]}, ‘uvas’: {‘información’: [[” ‘,’ 2001 ‘,’ bueno ‘]]}},’ rojo ‘: {‘ cerezas ‘: {‘ información ‘: [[‘ 5 ‘ , ‘1999’, ‘pendiente’]]}, ‘apple’: {‘info’: [[”, ”, ‘1970’, ‘good’], [‘5’, ‘1922’, ‘okay’]] }}}

Puede usar un fruitInfo aquí con una lista para mantener su fruitInfo y una tupla de 2 como su clave (color y fruta) y luego reformatear, por ejemplo:

 import csv from collections import defaultdict dd = defaultdict(list) with open('yourfile.csv') as fin: csvin = csv.DictReader(fin) for row in csvin: dd[row['color'], row['fruit']].append([row['count'], row['year'], row['info']]) 

Luego un ligero cambio de formato de dd usando:

 reformatted = [{'color': c, 'fruit': {'name': f, 'fruitInfo': v}} for (c, f), v in dd.items()] 

Te dio:

 [{'color': 'orange', 'fruit': {'fruitInfo': [['7', '1952', 'okay']], 'name': 'carrot'}}, {'color': 'green', 'fruit': {'fruitInfo': [['12', '2001', 'good']], 'name': 'grapes'}}, {'color': 'orange', 'fruit': {'fruitInfo': [['2', '1935', 'okay']], 'name': 'orange'}}, {'color': 'red', 'fruit': {'fruitInfo': [['3', '1970', 'good'], ['5', '1922', 'okay']], 'name': 'apple'}}, {'color': 'red', 'fruit': {'fruitInfo': [['5', '1999', 'outstanding']], 'name': 'cherries'}}, {'color': 'green', 'fruit': {'fruitInfo': [['22', '2001', 'marginal'], ['2', '2014', 'good']], 'name': 'celery'}}] 

La respuesta de Jon Clements es la solución óptima. Si quería algo un poco más en línea con la forma en que originalmente comenzó a ayudar a saber dónde podría haber salido mal, eche un vistazo a esto:

 results_list = [] colorFruitTuple_set = set() for row in reader: info_list = [row['count'], row['year'],row['info']] if (row['color'], row['fruit']) not in colorFruitTuple_set: color_dict = {} fruit_dict = {} color_dict['color'] = row['color'] fruit_dict['name'] = row['fruit'] list_of_info_lists = [info_list] fruit_dict['fruitInfo'] = list_of_info_lists color_dict['fruit'] = fruit_dict results_list.append(color_dict) colorFruitTuple_set.add((row['color'], row['fruit'])) else: for color_dict in results_list: if color_dict["color"] == row['color'] and color_dict["fruit"]["name"] == row["fruit"]: color_dict["fruit"]["fruitInfo"].append(info_list) 

Creo que eso es lo que buscabas. Estaba intentando usar el mismo color_dict y fruit_dict cuando necesitaba crear varios, lo que también significa que tampoco puede usarlo para hacer un seguimiento de los duplicados. Sin embargo, esto es solo para fines de aprendizaje, la manera en que Jon es la forma correcta de hacerlo.

¡Espero que esto ayude!