2017-07-25 3 views
0

Ich versuche, ein Element aus allen Zeilen in einer CSV, die eine Übereinstimmung mit jedem Schlüssel in einem Wörterbuch mit Python 2.7 enthalten zurückzugeben.Zeilen von csv durch Zuordnen zu Wörterbuchschlüssel python

Ich habe den folgenden Code versucht

with open(r"root\to\file", "r") as inFile: 
    for k in myDict.keys(): 
     reader = csv.reader(inFile) 
     result = [row[11] for row in reader if row[3] == k] 
     print(result) 

als Ausgang ich eine erfolgreiche Liste und dann die richtige Anzahl von leeren Listen.

Kann mir jemand sagen, warum es nur für den ersten Schlüssel funktioniert?

Vielen Dank im Voraus

Antwort

0

Der Grund, warum es nur für den ersten Schlüssel funktioniert, ist, dass beim Lesen einer Datei eine Dateiposition am Anfang der Datei steht, wenn die Lesung beginnt und am Ende der Datei, wenn die Lesung endet . Nach dem ersten Schlüssel hat der Leser das Ende der Datei erreicht und kehrt nicht automatisch zum Anfang der Datei zurück.

Ich sehe drei Lösungen mindestens

Legen Sie eine Liste aller Zeilen

with open(r"root\to\file", "r") as inFile: 
    row_list = list(csv.reader(inFile)) 
for k in myDict: 
    result = [row[11] for row in row_list if row[3] == k] 
    print(result) 

Shop nur die passenden Elemente in einem Wörterbuch

Dies ist meine bevorzugte Lösung.Jede Zeile wird nur einmal

from collections import defaultdict 
result_dict = defaultdict(list) 
with open(r"root\to\file", "r") as inFile: 
    for row in csv.reader(infile): 
     if row[3] in myDict: 
      result_dict[row[3]].append(row[11]) 
for k, result in result_dict.items(): 
    print(k, result) 

geprüft zu Beginn der Datei bei jeder Iteration

Zurück Der Vorteil ist, dass wir nicht brauchen, alles zu speichern, aber es ist ungewöhnlich, auszuführen viele file.seek Operationen, so würde ich lieber die Zeilen speichern, wenn die Größe der CSV-Datei nicht zu groß ist.

with open(r"root\to\file", "r") as inFile: 
    reader = csv.reader(inFile) 
    for k in myDict: 
     inFile.seek(0) 
     result = [row[11] for row in reader if row[3] == k] 
     print(result) 
+0

danke für deine Hilfe! Ich habe versucht, Ihre Top-Lösung, aber ich bekomme immer noch nur eine Antwort, jetzt ohne die leeren Listen ... irgendwelche Ideen? – pythonNovice

+0

Ich sehe nicht, wie es scheitern könnte. Haben Sie die Lösung kopiert und eingefügt? Vielleicht gibt es nur einen Diktatschlüssel, der gleich einer Zeile [3] ist? Sie könnten 'row_list' drucken, um zu sehen, wie es aussieht. – Gribouillis

+0

Ich übergab Variablen über Funktionen, wenn ich Ihre Lösung kopiere/einfüge, liefert sie, was ich brauche. – pythonNovice

0

Kann mir jemand sagen, warum es nur für den ersten Schlüssel zu arbeiten?

reader = csv.reader (inFile) öffnet die Datei und beginnt mit dem Reeding von Anfang bis Ende. Es wird dann den Cursor am Ende verlassen. In den folgenden Iterationen hat es nichts zu lesen.

Wie behebt man diese (Quick-Fix-Version)?

with open(r"root\to\file", "r") as inFile: 
    for k in myDict.keys(): 
     reader = csv.reader(inFile) 
     inFile.seek(0) # move cursor to start 
     result = [row[11] for row in reader if row[3] == k] 
     print(result) 

Erklärung

Ich werde erläutern, was ich meine. Zuerst möchte ich Ihnen einige Beispieldaten geben, die ich in eine Datei schreibe (csv-Format).

import csv 

dict_ = {"1":1, "2":3} 

data = """date,id,weight 
01/01/1991,1,293 
01/02/1991,2,291 
01/03/1991,3,289 
""" 

with open("output.txt","wt") as f: 
    f.write(data) 

Nichtarbeitsbeispiel:

with open("output.txt") as f: 
    for keys in dict_: 
     reader = csv.reader(f) # <-- Opens file and reads it (cursor in end) 
     print([i for i in reader]) 

## Output 
# >> [['date', 'id', 'weight'], ['01/01/1991', '1', '293'], ['01/02/1991', '2', '291'], ['01/03/1991', '3', '289']] 
# >> [] 

Stattdessen verwenden:

with open("output.txt") as f: 
    for keys in dict_: 
     reader = csv.reader(f) # <-- Opens file and reads it (cursor in end) 
     f.seek(0) # <-- Return cursor to 0 (cursor is now in the start) 
     print([i for i in reader]) 

## Output 
# >> [['date', 'id', 'weight'], ['01/01/1991', '1', '293'], ['01/02/1991', '2', '291'], ['01/03/1991', '3', '289']] 
# >> [['date', 'id', 'weight'], ['01/01/1991', '1', '293'], ['01/02/1991', '2', '291'], ['01/03/1991', '3', '289']] 

Oder einfach es zu einer lokalen Variablen zuerst lesen:

with open("output.txt") as f: 
    csvdata = list(csv.reader(f)) #or this 

for key in dict_.keys(): 
    [print(i) for i in csvdata if i[1] == key] 

## Output 
# >> ['01/01/1991', '1', '293'] 
# >> ['01/02/1991', '2', '291'] 
+0

Vielen Dank für diese sehr hilfreiche Erklärung. Ich habe die Antwort von Gribouillis akzeptiert, da sie mehr Möglichkeiten bietet. Ich werde diese Antwort abstimmen, aber da ich <15 Punkte habe, wird es nicht angezeigt. Danke nochmal – pythonNovice

0

Sie müssen Öffnen Sie die Datei jedes Mal erneut. Also invertiere die with- und for-Anweisungen.

Für die Effizienz würde ich empfehlen, Pandas zu verwenden, um den CSV zu lesen, so dass Sie den resultierenden Datenrahmen viele Male abfragen können.

Verwandte Themen