web-dev-qa-db-ja.com

Python CSVを正しく解析する

私はPythonが初めてです。引用された値を認識するようにcsvファイルを解析したい-例えば

1997、フォード、E350、「スーパー、豪華なトラック」

として分割する必要があります

(「1997」、「フォード」、「E350」、「スーパー、豪華なトラック」)

とない

(「1997」、「フォード」、「E350」、「「スーパー」、「豪華なトラック」」)

上記はstr.split(,)のようなものを使用した場合に得られるものです。

どうすればいいですか?また、これらの値を配列または他のデータ構造に保存するのが最善でしょうか? csvからこれらの値を取得した後、簡単に選択できるようにしたいので、任意の2つの列を指定して、別の配列または他のデータ構造として保存します。

23
cornerstone

次の方法は完全に機能しました

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

列は、列名をキーとして辞書に保存されます。

14
cornerstone

csvモジュールを使用する必要があります。

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

出力:

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

csv.reader()ステートメント内でquotecharとして二重引用符を定義する必要があります。

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

CSVモジュールを使用したくない場合は、正規表現を使用する必要があります。これを試して:

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

あなたがしようとした場合:

print(array[3])

あなたが取得します:

"Super, luxurious truck"
4
Reimar

Csv.pyモジュールはおそらく大丈夫です-しかし、それがどのように動作するかを見たり制御したい場合は、ここに小さなpythonコルーチンに基づく唯一のソリューションがあります:

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"')

テスト済みpython 2.7

0
Vernon Crabtree