Importer le csv Python dans la liste

194

J'ai un fichier CSV avec environ 2000 enregistrements.

Chaque enregistrement a une chaîne et une catégorie:

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

J'ai besoin de lire ce fichier dans une liste qui ressemble à ceci:

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

Comment importer ce CSV dans la liste dont j'ai besoin en utilisant Python?

MorganTN
la source
2
Ensuite, utilisez le csvmodule: docs.python.org/2/library/csv.html
furas
4
S'il y a une réponse qui convient à votre question, veuillez l'accepter.
Maciej Gol

Réponses:

308

Utilisation du module csv :

import csv

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

print(data)

Production:

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

Si vous avez besoin de tuples:

import csv

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

print(data)

Production:

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

Ancienne réponse Python 2, utilisant également le csvmodule:

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']]
Maciej Gol
la source
4
Pourquoi utilisez-vous «rb» au lieu de «r»?
imrek
5
@DrunkenMaster, bprovoque l'ouverture du fichier en mode binaire par opposition au mode texte. Sur certains systèmes, le mode texte signifie qu'il \nsera converti en nouvelle ligne spécifique à la plate-forme lors de la lecture ou de l'écriture. Voir la documentation .
Maciej Gol
7
Cela ne fonctionne pas dans Python 3.x: "csv.Error: l'itérateur doit renvoyer des chaînes, pas des octets (avez-vous ouvert le fichier en mode texte?)" Voir ci-dessous la réponse qui fonctionne dans Python 3.x
Gilbert
2
pour gagner quelques secondes de débogage, vous devriez probablement ajouter une note pour la première solution, comme "Python 2.x version"
paradite
Comment utiliser votre 1ère solution mais avec seulement quelques colonnes du fichier csv?
Sigur
54

Mis à jour pour Python 3 :

import csv

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

print(your_list)

Production:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]
seokhoonlee
la source
La spécification 'r'est le mode par défaut, il n'est donc pas nécessaire de la spécifier. La documentation mentionne également si csvfile est un objet fichier, il doit être ouvert avec newline = ''.
AMC
44

Pandas est assez doué pour traiter les données. Voici un exemple de son utilisation:

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()

Un gros avantage est que les pandas traitent automatiquement les lignes d'en-tête.

Si vous n'avez pas entendu parler de Seaborn , je vous recommande d'y jeter un œil.

Voir aussi: Comment lire et écrire des fichiers CSV avec 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')

Le contenu de df est:

     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

Le contenu des dicts est

[{'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')]

Le contenu de listsest:

[['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]]
Martin Thoma
la source
tuples = [tuple(x) for x in df.values]peut être écrit à la tuples = list(df.itertuples(index=False))place. Notez que les documents Pandas découragent l'utilisation de .valuesen faveur de .to_numpy(). Le troisième exemple me déroute. Premièrement, parce que la variable est nommée tuples, ce qui impliquerait qu'il s'agit d'une liste de tuples, alors que c'est en fait une liste de listes. Deuxièmement, parce que pour autant que je sache, cette expression entière peut être remplacée par df.to_list(). Je ne sais pas non plus si le deuxième exemple est vraiment pertinent ici.
AMC
9

Mise à jour pour 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)

Production:

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

Si csvfile est un objet fichier, il doit être ouvert avec newline=''.
module csv

Calcul
la source
Pourquoi utiliser list(map())sur une liste de compréhension? Notez également l'espace blanc au début de chaque élément de la deuxième colonne.
AMC le
5

Si vous êtes sûr qu'il n'y a pas de virgules dans votre entrée, autre que pour séparer la catégorie, vous pouvez lire la ligne de fichiers en ligne et divisez sur ,, puis appuyez sur le résultatList

Cela dit, il semble que vous regardez un fichier CSV, vous pouvez donc envisager d'utiliser les modules correspondants.

Miquel
la source
4
result = []
for line in text.splitlines():
    result.append(tuple(line.split(",")))
Serpent_Acide
la source
1
Pouvez-vous s'il vous plaît ajouter un peu d'explication à ce message? Seul le code est (parfois) bon, mais le code et l'explication sont (la plupart du temps) meilleurs
Barranka
3
Je sais que le commentaire de Barranka a plus d'un an, mais pour tous ceux qui trébuchent là-dessus et ne peuvent pas le comprendre: for line in text.splitlines (): met chaque ligne individuelle dans la variable temp "line". line.split (",") crée une liste de chaînes séparées par une virgule. tuple (~) place cette liste dans un tuple et append (~) l' ajoute au résultat. Après la boucle, le résultat est une liste de tuples, avec chaque tuple une ligne et chaque élément de tuple un élément dans le fichier csv.
Louis
En plus de ce que @Louis a dit, il n'est pas nécessaire d'utiliser .read().splitlines(), vous pouvez parcourir directement chaque ligne du fichier: for line in in_file: res.append(tuple(line.rstrip().split(",")))Notez également que l'utilisation .split(',')signifie que chaque élément de la deuxième colonne commencera par un espace supplémentaire.
AMC le
Addendum au code que je viens de partager ci-dessus: line.rstrip()-> line.rstrip('\n').
AMC le
3

Comme déjà dit dans les commentaires, vous pouvez utiliser la csvbibliothèque en python. csv signifie des valeurs séparées par des virgules qui semblent exactement votre cas: une étiquette et une valeur séparées par une virgule.

Étant un type de catégorie et de valeur, je préférerais utiliser un type de dictionnaire au lieu d'une liste de tuples.

Quoi qu'il en soit, dans le code ci-dessous, je montre les deux façons: dest le dictionnaire et lest la liste des tuples.

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)
Francesco Boi
la source
Pourquoi ne pas utiliser un gestionnaire de contexte pour gérer le fichier? Pourquoi mélangez-vous deux conventions de dénomination de variables différentes? N'est-ce pas (row[0], row[1])plus faible / plus sujet aux erreurs que la simple utilisation tuple(row)?
AMC
Pourquoi pensez-vous que faire un tuple (ligne) est moins sujet aux erreurs? À quelle convention de dénomination des variables faites-vous référence? Veuillez lier une convention de dénomination Python officielle. Pour autant que je sache, try -except est un bon moyen de gérer les fichiers: qu'entendez-vous par gestionnaire de contexte?
Francesco Boi le
Pourquoi pensez-vous que faire un tuple (ligne) est moins sujet aux erreurs? Parce qu'il ne nécessite pas que vous écriviez chaque index manuellement. Si vous faites une erreur ou que le nombre d'éléments change, vous devez revenir en arrière et changer votre code. Le try-except est très bien, les gestionnaires de contexte sont l'instruction with. Vous pouvez trouver de nombreuses ressources sur le sujet, comme celle- ci.
AMC
Je ne vois pas comment le gestionnaire de contexte serait meilleur que le vieux bon bloc try-except. Pour l'autre, l'aspect positif est que vous tapez moins de code; pour le reste si le nombre d'éléments (je suppose que tu veux dire le nombre de colonnes) change le mien, c'est mieux car il n'extrait que les valeurs souhaitées tandis que l'autre extrait tout l'excel. Sans aucune exigence spécifique, vous ne pouvez pas dire ce qui est mieux, c'est donc une perte de temps à discuter de ce qui est mieux: dans ce cas, les deux sont valables
Francesco Boi
Je ne vois pas comment le gestionnaire de contexte serait meilleur que le vieux bon bloc try-except. S'il vous plaît voir mon commentaire précédent, le gestionnaire de contexte ne remplacerait pas le try-except.
AMC
2

Une simple boucle suffirait:

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

print lines
Hunter McMillen
la source
1
Que faire si certaines entrées comportent des virgules?
Tony Ennis
@TonyEnnis Ensuite, vous devrez utiliser une boucle de traitement plus avancée. La réponse de Maciej ci-dessus montre comment utiliser l'analyseur csv fourni avec Python pour effectuer cette opération. Cet analyseur a probablement toute la logique dont vous avez besoin.
Hunter McMillen
1

Malheureusement, je ne trouve aucune des réponses existantes particulièrement satisfaisante.

Voici une solution Python 3 simple et complète, utilisant le module csv .

import csv

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

print(rows)

Remarquez l' skipinitialspace=Trueargument. Ceci est nécessaire car, malheureusement, le CSV d'OP contient des espaces après chaque virgule.

Production:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]
AMC
la source
0

En étendant un peu vos besoins et en supposant que vous ne vous souciez pas de l'ordre des lignes et que vous souhaitez les regrouper sous catégories, la solution suivante peut fonctionner pour vous:

>>> 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 cette façon, vous obtenez toutes les lignes pertinentes disponibles dans le dictionnaire sous la clé étant la catégorie.

Jan Vlcinsky
la source
0

Voici le moyen le plus simple en Python 3.x d'importer un CSV dans un tableau multidimensionnel, et ses seulement 4 lignes de code sans rien importer!

#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)
Jason Boucher
la source
Attention, c'est une liste, pas un tableau! Pourquoi ne pas utiliser un gestionnaire de contexte pour gérer correctement l'objet fichier? Notez que cette solution laisse des espaces supplémentaires sur le deuxième élément de chaque ligne et qu'elle échouera si l'une des données contient une virgule.
AMC
-1

Vient ensuite un morceau de code qui utilise le module csv mais extrait le contenu du fichier.csv dans une liste de dictionnaires en utilisant la première ligne qui est un en-tête de la table 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
Alexey Antonenko
la source
1
Pourquoi ne pas simplement utiliser csv.DictReader?
AMC le