Python importa csv a la lista


193

Tengo un archivo CSV con aproximadamente 2000 registros.

Cada registro tiene una cadena y una categoría:

This is the first line,Line1
This is the second line,Line2
This is the third line,Line3

Necesito leer este archivo en una lista que se ve así:

data = [('This is the first line', 'Line1'),
        ('This is the second line', 'Line2'),
        ('This is the third line', 'Line3')]

¿Cómo puedo importar este CSV a la lista que necesito usando Python?


2
Luego use el csvmódulo: docs.python.org/2/library/csv.html
furas

44
Si hay una respuesta que se adapte a su pregunta, acéptela.
Maciej Gol

Respuestas:


305

Usando el módulo csv :

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    data = list(reader)

print(data)

Salida:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]

Si necesitas tuplas:

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    data = [tuple(row) for row in reader]

print(data)

Salida:

[('This is the first line', 'Line1'), ('This is the second line', 'Line2'), ('This is the third line', 'Line3')]

Antigua respuesta de Python 2, también usando el csvmódulo:

import csv
with open('file.csv', 'rb') as f:
    reader = csv.reader(f)
    your_list = list(reader)

print your_list
# [['This is the first line', 'Line1'],
#  ['This is the second line', 'Line2'],
#  ['This is the third line', 'Line3']]

44
¿Por qué usas 'rb' en lugar de 'r'?
imrek

55
@DrunkenMaster, bhace que el archivo se abra en modo binario en lugar de modo de texto. En algunos sistemas, el modo de texto significa que \nse convertirá en una nueva línea específica de la plataforma al leer o escribir. Ver documentos .
Maciej Gol

77
Esto no funciona en Python 3.x: "csv.Error: el iterador debe devolver cadenas, no bytes (¿abrió el archivo en modo de texto?)" Consulte a continuación la respuesta que funciona en Python 3.x
Gilbert

2
para ahorrar unos segundos de depuración, probablemente debería agregar una nota para la primera solución, como "versión Python 2.x"
paradita

¿Cómo usar su primera solución pero solo con algunas columnas del archivo csv?
Sigur

54

Actualizado para Python 3 :

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    your_list = list(reader)

print(your_list)

Salida:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]

Especificar 'r'es el modo predeterminado, por lo que no es necesario especificarlo. Los documentos también mencionan si csvfile es un objeto de archivo, debe abrirse con newline = ''.
AMC

44

Pandas es bastante bueno en el manejo de datos. Aquí hay un ejemplo de cómo usarlo:

import pandas as pd

# Read the CSV into a pandas data frame (df)
#   With a df you can do many things
#   most important: visualize data with Seaborn
df = pd.read_csv('filename.csv', delimiter=',')

# Or export it in many ways, e.g. a list of tuples
tuples = [tuple(x) for x in df.values]

# or export it as a list of dicts
dicts = df.to_dict().values()

Una gran ventaja es que los pandas manejan automáticamente las filas de encabezado.

Si no has oído hablar de Seaborn , te recomiendo echarle un vistazo.

Ver también: ¿Cómo leo y escribo archivos CSV con Python?

Pandas # 2

import pandas as pd

# Get data - reading the CSV file
import mpu.pd
df = mpu.pd.example_df()

# Convert
dicts = df.to_dict('records')

El contenido de df es:

     country   population population_time    EUR
0    Germany   82521653.0      2016-12-01   True
1     France   66991000.0      2017-01-01   True
2  Indonesia  255461700.0      2017-01-01  False
3    Ireland    4761865.0             NaT   True
4      Spain   46549045.0      2017-06-01   True
5    Vatican          NaN             NaT   True

El contenido de los dictados es

[{'country': 'Germany', 'population': 82521653.0, 'population_time': Timestamp('2016-12-01 00:00:00'), 'EUR': True},
 {'country': 'France', 'population': 66991000.0, 'population_time': Timestamp('2017-01-01 00:00:00'), 'EUR': True},
 {'country': 'Indonesia', 'population': 255461700.0, 'population_time': Timestamp('2017-01-01 00:00:00'), 'EUR': False},
 {'country': 'Ireland', 'population': 4761865.0, 'population_time': NaT, 'EUR': True},
 {'country': 'Spain', 'population': 46549045.0, 'population_time': Timestamp('2017-06-01 00:00:00'), 'EUR': True},
 {'country': 'Vatican', 'population': nan, 'population_time': NaT, 'EUR': True}]

Pandas # 3

import pandas as pd

# Get data - reading the CSV file
import mpu.pd
df = mpu.pd.example_df()

# Convert
lists = [[row[col] for col in df.columns] for row in df.to_dict('records')]

El contenido de listses:

[['Germany', 82521653.0, Timestamp('2016-12-01 00:00:00'), True],
 ['France', 66991000.0, Timestamp('2017-01-01 00:00:00'), True],
 ['Indonesia', 255461700.0, Timestamp('2017-01-01 00:00:00'), False],
 ['Ireland', 4761865.0, NaT, True],
 ['Spain', 46549045.0, Timestamp('2017-06-01 00:00:00'), True],
 ['Vatican', nan, NaT, True]]

tuples = [tuple(x) for x in df.values]se puede escribir en su tuples = list(df.itertuples(index=False))lugar. Tenga en cuenta que los documentos de Pandas desalientan el uso de .valuesa favor de .to_numpy(). El tercer ejemplo es confuso para mí. Primero, porque se nombra la variable tuples, lo que implicaría que es una lista de tuplas, mientras que en realidad es una lista de listas. Segundo, porque hasta donde puedo decir, esa expresión completa puede ser reemplazada por df.to_list(). Tampoco sé si el segundo ejemplo es realmente relevante aquí.
AMC

9

Actualización para Python3:

import csv
from pprint import pprint

with open('text.csv', newline='') as file:
    reader = csv.reader(file)
    res = list(map(tuple, reader))

pprint(res)

Salida:

[('This is the first line', ' Line1'),
 ('This is the second line', ' Line2'),
 ('This is the third line', ' Line3')]

Si csvfile es un objeto de archivo, debe abrirse con newline=''.
módulo csv


¿Por qué usar list(map())sobre una lista de comprensión? Además, observe el espacio en blanco al comienzo de cada elemento de la segunda columna.
AMC


4
result = []
for line in text.splitlines():
    result.append(tuple(line.split(",")))

1
¿Puedes por favor agregar un poco de explicación a esta publicación? El código solo es (a veces) bueno, pero el código y la explicación son (la mayoría de las veces) mejores
Barranka

3
Sé que el comentario de Barranka tiene más de un año, pero para cualquiera que se encuentre con esto y no pueda resolverlo: for line in text.splitlines (): coloca cada línea individual en la variable temporal "line". line.split (",") crea una lista de cadenas que se dividen en la coma. tupla (~) pone esa lista en una tupla y anexa (~) la agrega al resultado. Después del ciclo, el resultado es una lista de tuplas, con cada tupla una línea, y cada elemento de la tupla un elemento en el archivo csv.
Louis

Además de lo que dijo @Louis, no hay necesidad de usarlo .read().splitlines(), puede iterar sobre cada línea del archivo directamente: for line in in_file: res.append(tuple(line.rstrip().split(",")))también, tenga en cuenta que usar .split(',')significa que cada elemento de la segunda columna comenzará con espacios en blanco adicionales.
AMC

Anexo al código que acabo de compartir arriba: line.rstrip()-> line.rstrip('\n').
AMC

3

Como ya se dijo en los comentarios, puede usar la csvbiblioteca en python. csv significa valores separados por comas que parece exactamente su caso: una etiqueta y un valor separados por una coma.

Al ser una categoría y un tipo de valor, preferiría usar un tipo de diccionario en lugar de una lista de tuplas.

De todos modos, en el siguiente código, muestro en ambos sentidos: des el diccionario y les la lista de tuplas.

import csv

file_name = "test.txt"
try:
    csvfile = open(file_name, 'rt')
except:
    print("File not found")
csvReader = csv.reader(csvfile, delimiter=",")
d = dict()
l =  list()
for row in csvReader:
    d[row[1]] = row[0]
    l.append((row[0], row[1]))
print(d)
print(l)

¿Por qué no usar un administrador de contexto para manejar el archivo? ¿Por qué está mezclando dos convenciones de nombres variables diferentes? ¿No es (row[0], row[1])más débil / más propenso a errores que simplemente usar tuple(row)?
AMC

¿Por qué crees que hacer tupla (fila) es menos propenso a errores? ¿A qué convención de nomenclatura variable te refieres? Enlace una convención oficial de nombres de python. Hasta donde sé, pruebe -excepto es una buena manera de manejar archivos: ¿qué quiere decir con controlador de contexto?
Francesco Boi

¿Por qué crees que hacer tupla (fila) es menos propenso a errores? Porque no requiere que escriba cada índice manualmente. Si comete un error, o la cantidad de elementos cambia, debe regresar y cambiar su código. El try-except está bien, los gestores de contexto son la declaración with. Puede encontrar muchos recursos sobre el tema, como este .
AMC

No veo cómo el administrador de contexto sería mejor que el antiguo bloque de buen intento. Para el otro, el aspecto positivo es que escribe menos código; para el resto, si el número de elementos (supongo que quiere decir el número de columnas) cambia, el mío es mejor porque está extrayendo solo los valores deseados, mientras que el otro extrae todo el excedente. Sin ningún requisito específico, no puede decir cuál es mejor, por lo que es una pérdida de tiempo discutir cuál es mejor: en este caso, ambos son válidos
Francesco Boi

No veo cómo el administrador de contexto sería mejor que el antiguo bloque de buen intento. Por favor, vea mi comentario anterior, el administrador de contexto no reemplazará el try-except.
AMC

2

Un simple bucle sería suficiente:

lines = []
with open('test.txt', 'r') as f:
    for line in f.readlines():
        l,name = line.strip().split(',')
        lines.append((l,name))

print lines

1
¿Qué pasa si algunas de las entradas tienen comas?
Tony Ennis

@TonyEnnis Entonces necesitaría usar un bucle de procesamiento más avanzado. La respuesta de Maciej anterior muestra cómo usar el analizador csv que viene con Python para realizar esta operación. Es muy probable que este analizador tenga toda la lógica que necesita.
Hunter McMillen

1

Lamentablemente, ninguna de las respuestas existentes me parece particularmente satisfactoria.

Aquí hay una solución simple y completa de Python 3, utilizando el módulo csv .

import csv

with open('../resources/temp_in.csv', newline='') as f:
    reader = csv.reader(f, skipinitialspace=True)
    rows = list(reader)

print(rows)

Note el skipinitialspace=Trueargumento. Esto es necesario ya que, desafortunadamente, el CSV de OP contiene espacios en blanco después de cada coma.

Salida:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]

0

Extendiendo un poco sus requisitos y suponiendo que no le importa el orden de las líneas y desea agruparlas en categorías, la siguiente solución puede funcionar para usted:

>>> fname = "lines.txt"
>>> from collections import defaultdict
>>> dct = defaultdict(list)
>>> with open(fname) as f:
...     for line in f:
...         text, cat = line.rstrip("\n").split(",", 1)
...         dct[cat].append(text)
...
>>> dct
defaultdict(<type 'list'>, {' CatA': ['This is the first line', 'This is the another line'], ' CatC': ['This is the third line'], ' CatB': ['This is the second line', 'This is the last line']})

De esta manera obtienes todas las líneas relevantes disponibles en el diccionario bajo la clave que es la categoría.


0

¡Aquí está la forma más fácil en Python 3.x de importar un CSV a una matriz multidimensional, y sus solo 4 líneas de código sin importar nada!

#pull a CSV into a multidimensional array in 4 lines!

L=[]                            #Create an empty list for the main array
for line in open('log.txt'):    #Open the file and read all the lines
    x=line.rstrip()             #Strip the \n from each line
    L.append(x.split(','))      #Split each line into a list and add it to the
                                #Multidimensional array
print(L)

¡Cuidado, es una lista, no una matriz! ¿Por qué no usar un administrador de contexto para manejar correctamente el objeto de archivo? Tenga en cuenta que esta solución deja espacios en blanco adicionales en el segundo elemento de cada fila, y que fallará si alguno de los datos contiene una coma.
AMC

-1

El siguiente es un fragmento de código que utiliza el módulo csv pero extrae el contenido de file.csv a una lista de dictados utilizando la primera línea, que es un encabezado de la tabla csv

import csv
def csv2dicts(filename):
  with open(filename, 'rb') as f:
    reader = csv.reader(f)
    lines = list(reader)
    if len(lines) < 2: return None
    names = lines[0]
    if len(names) < 1: return None
    dicts = []
    for values in lines[1:]:
      if len(values) != len(names): return None
      d = {}
      for i,_ in enumerate(names):
        d[names[i]] = values[i]
      dicts.append(d)
    return dicts
  return None

if __name__ == '__main__':
  your_list = csv2dicts('file.csv')
  print your_list

1
¿Por qué no solo usar csv.DictReader?
AMC
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.