En Python tengo una lista de diccionarios como este:

[
    {
        "col2": "2",
        "id": "1",
        "col3": "3",
        "col1": "1"
    },
    {
        "col2": "4",
        "id": "2",
        "col3": "6",
        "col1": "2"
    },
    {
        "col1": "1",
        "col2": "4",
        "id": "3",
        "col3": "7"
    }
]

Y necesito convertir esto a una cadena en formato csv que incluye una fila de encabezado. (Para empezar, no nos preocupemos por los delimitadores de columna y fila ...) Entonces, idealmente, el resultado sería:

id,col1,col2,col3
1,1,2,3
2,2,4,6
3,1,4,7

("idealmente" porque el orden de las columnas realmente no importa; tener la columna "id" primero sería bueno, aunque ...)

He buscado SOF y hay varias preguntas similares, pero las respuestas siempre implican crear un archivo csv usando csv.DictWriter. No quiero crear un archivo, ¡solo quiero esa cadena!

Por supuesto, podría recorrer la lista y dentro de este bucle sobre las teclas del diccionario y de esta manera crear la cadena csv usando operaciones de cadena. ¿Pero seguramente debe haber alguna forma más elegante y eficiente de hacer esto?

Además, conozco la biblioteca Pandas, pero estoy tratando de hacer esto en un entorno muy limitado en el que preferiría usar solo módulos integrados.

0
Kai Roesner 8 oct. 2019 a las 12:12

4 respuestas

La mejor respuesta

Puede usar io.StringIO para escribir en un 'cadena' en lugar de un archivo. Usando el ejemplo de csv.DictWriter obtenemos el siguiente código:

import csv
import io

data = [...]  # your list of dicts

with io.StringIO() as csvfile:
    fieldnames = ['id', 'col1', 'col2', 'col3']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()
    for row in data:
        writer.writerow(row)
    print(csvfile.getvalue())
0
ikkuh 8 oct. 2019 a las 09:28

La forma más fácil sería usar pandas:

import pandas as pd
df = pd.DataFrame.from_dict(your_list_of_dicts)
print(df.to_csv(index=False))

Resultado:

col1,col2,col3,id
1,2,3,1
2,4,6,2
1,4,7,3

Si desea reordenar columnas, nada más fácil:

col_order = ['id', 'col1', 'col2', 'col3']
df[col_order].to_csv(index=False)

O, para asegurarse de que la columna id sea la primera:

df.set_index('id', inplace=True) # the index is always printed first
df.to_csv() # leave the index to True this time
3
Derlin 8 oct. 2019 a las 09:15

Con características incorporadas:

from collections import OrderedDict

ord_d = OrderedDict().fromkeys(('id', 'col1', 'col2', 'col3'))
s = ','.join(ord_d.keys()) + '\n'
for d in lst:
    ord_d.update(d)
    s += ','.join(ord_d.values()) + '\n'

print(s)

La salida:

id,col1,col2,col3
1,1,2,3
2,2,4,6
3,1,4,7
2
RomanPerekhrest 8 oct. 2019 a las 09:30

La idea es obtener todas las claves posibles y obtener todos los valores. Supongamos que los datos son la lista de dictos que tiene. Esto debería funcionar:

output = ''
all_keys = set().union(*(d.keys() for d in data))
output += ",".split(all_keys) + '\n'
for item in data:
    item_str = ",".split([data[key] for key in all_keys if key in data else ''])
    output += item_str + '\n'

Fuente

0
pabsldn 8 oct. 2019 a las 09:24
58283350