web-dev-qa-db-fra.com

Python Parse CSV correctement

Je suis très nouveau sur Python. Je veux analyser un fichier csv tel qu'il reconnaîtra les valeurs entre guillemets - par exemple 

1997, Ford, E350, "Super, camion luxueux"

devrait être divisé en 

('1997', 'Ford', 'E350', 'Super, camion luxueux')

et pas

('1997', 'Ford', 'E350', '' Super ',' camion luxueux '')

ce qui précède correspond à ce que je reçois si j’utilise quelque chose comme str.split(,).

Comment puis-je faire cela? De plus, serait-il préférable de stocker ces valeurs dans un tableau ou dans une autre structure de données? parce qu'après avoir obtenu ces valeurs du csv, je veux pouvoir choisir facilement, disons n'importe laquelle des colonnes et stockons-le sous un autre tableau ou une autre structure de données.

20
cornerstone

La méthode suivante a parfaitement fonctionné

d = {}
d['column1name'] = []
d['column2name'] = []
d['column3name'] = []

dictReader = csv.DictReader(open('filename.csv', 'rb'), fieldnames = ['column1name', 'column2name', 'column3name'], delimiter = ',', quotechar = '"')

for row in dictReader:
    for key in row:
        d[key].append(row[key])

Les colonnes sont stockées dans un dictionnaire avec les noms de colonne comme clé.

14
cornerstone

Vous devriez utiliser le module csv:

import csv
reader = csv.reader(['1997,Ford,E350,"Super, luxurious truck"'], skipinitialspace=True)
for r in reader:
    print r

sortie:

['1997', 'Ford', 'E350', 'Super, luxurious truck']
22
akhter wahab

Vous devez définir le guillemet double en tant que quotechar dans l'instruction csv.reader():

>>> with open(r'<path_to_csv_test_file>') as csv_file:
...     reader = csv.reader(csv_file, delimiter=',', quotechar='"')
...     print(reader.next())
... 
['1997', 'Ford', 'E350', 'Super, luxurious truck']
>>> 
5
Colin O'Coal

Si vous ne souhaitez pas utiliser le module CSV, vous devez utiliser une expression régulière. Essaye ça:

import re
array = re.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", '1997,Ford,E350,"Super, luxurious truck"')

Si tu essayes:

print(array[3])

tu auras:

"Super, luxurious truck"
3
Reimar

Le module csv.py convient probablement, mais si vous souhaitez voir et/ou contrôler son fonctionnement, voici une petite solution basée uniquement sur Python et basée sur un coroutine:

def csv_parser(delimiter=','):
    field = []
    while True:
        char = (yield(''.join(field)))
        field = []

        leading_whitespace = []    
        while char and char == ' ':
            leading_whitespace.append(char)
            char = (yield)

        if char == '"' or char == "'":
            suround = char
            char = (yield)
            while True:
                if char == suround:
                    char = (yield)
                    if not char == suround:
                        break

                field.append(char)
                char = (yield)

            while not char == delimiter:
                if char == None:
                    (yield(''.join(field)))
                char = (yield)
        else:
            field = leading_whitespace
            while not char == delimiter:
                if char == None:
                    (yield(''.join(field)))
                field.append(char)
                char = (yield)

def parse_csv(csv_text):
    processor = csv_parser()
    processor.next() # start the processor coroutine

    split_result = []
    for c in list(csv_text) + [None]:
        emit = processor.send(c)
        if emit:
            split_result.append(emit)

    return split_result

print parse_csv('1997,Ford,E350,"Super, luxurious truck"')

Testé sur Python 2.7

0
Vernon Crabtree