1

ID;Col1;Col2;Col3;Col4;Col5Python 3.3.0 を使用して、csv ファイル (ヘッダー: )から「辞書」を作成しました。

ID;Col1;Col2;Col3;Col4;Col5
15345;1;1;nnngngn;vhrhtnz;latest
12345;12;8;gnrghrtthr;tznhltrnhklr;latest
90834;3;4;something;nonsens;latest
12345;34;235;dontcare;muhaha;oldone

コード付き

file = "test.csv" 
csv_file = csv.DictReader(open(file, 'r'), delimiter=';', quotechar='"')

ID = 12345 の行をファイルではなく新しい辞書にコピーしたかったのです。列名を直接アドレス指定できるようにしたかったので、リストではなく辞書にコピーする必要がありました。私はこれをやってみました

cewl = {}
for row in csv_file:
   if row['ID'] == '12345':
   cewl.update(row)
print(cewl)

出力は次のとおりです。

{'ID': '12345', 'Col1': '34', 'Col2': '235', 'Col3': 'dontcare', 'Col4': 'muhaha', 'Col5': 'oldone'}

私の問題: ID=12345 の 2 行目のみがコピーされ、最初の行は省略されています。理由はわかりません。

新しいリストにコピーしてこれを試すと(テスト目的のみ)、すべて正常に機能します。

cewl = []
for row in csv_file1:
if row['ID'] == '12345':
    cewl.append(row)
print(cewl)

出力は次のとおりです。

[{'Col3': 'gnrghrtthr', 'Col2': '8', 'Col1': '12', 'Col5': 'latest', 'Col4': 'tznhltrnhklr', 'ID': '12345'}, 
{'Col3': 'dontcare', 'Col2': '235', 'Col1': '34', 'Col5': 'oldone', 'Col4': 'muhaha', 'ID': '12345'}]

なぜこれが新しい辞書にコピーしてもうまくいかないのかわかりません... dictreader の .add や .append のようなメソッドはないようです。

行を失うことなくデータを新しい辞書にコピーするにはどうすればよいですか?

4

1 に答える 1

2

期待される出力は何ですか?;の動作は完全に正常ですdict。各キーの値を新しい値に置き換えています。

値を一致する各行の値のリストにしたい場合は、ファクトリdefaultdictで aを使用する方が簡単です。list

from collections import defaultdict

cewl = defaultdict(list)

for row in csv_file:
   if row['ID'] == '12345':
       for k, v in row.items():
           cewl[k].append(v)

print(cewl)

これは以下を出力します:

defaultdict(<class 'list'>, {'Col1': ['12', '34'], 'ID': ['12345', '12345'], 'Col2': ['8', '235'], 'Col5': ['latest', 'oldone'], 'Col4': ['tznhltrnhklr', 'muhaha'], 'Col3': ['gnrghrtthr', 'dontcare']})

Adefaultdictは のサブクラスでdictあるため、print(cewl['Col1'])が出力されます['12', '34']

.update()効果的に使用する場合は、次のようにします。

for k, v in row.items():
    cewl[k] = v

cewlたとえば、処理中の行で見つかった値に各キーを設定します。最後の行が処理されると、その値が前の行の値を上書きします。

特定の条件に一致する行だけを除外したい場合はID、それらをリストに追加するだけで十分です。次に、一致した結果をループして処理します。

for row in cewl:
    # do something with matched row

または、フィルター処理を行うためにラップするジェネレーターフィルターを作成できるため、DictReader()メモリ内にリストを作成する必要はありません。

def rowfilter(reader, id):
    for row in reader:
        if row['ID'] == id:
            yield row

for row in rowfilter(csv_file, '12345'):
    # do something with matched row
于 2013-02-12T10:30:29.880 に答える