Überspringen Sie die Header, wenn Sie eine CSV-Datei mit Python bearbeiten

208

Ich verwende den unten angegebenen Code, um eine CSV mit Python zu bearbeiten. Im Code aufgerufene Funktionen bilden den oberen Teil des Codes.

Problem: Ich möchte, dass der unten angegebene Code die Bearbeitung der CSV aus der 2. Zeile startet. Ich möchte, dass die 1. Zeile, die Überschriften enthält, ausgeschlossen wird. Im Moment werden die Funktionen nur in der 1. Zeile angewendet und meine Kopfzeile wird geändert.

in_file = open("tmob_notcleaned.csv", "rb")
reader = csv.reader(in_file)
out_file = open("tmob_cleaned.csv", "wb")
writer = csv.writer(out_file)
row = 1
for row in reader:
    row[13] = handle_color(row[10])[1].replace(" - ","").strip()
    row[10] = handle_color(row[10])[0].replace("-","").replace("(","").replace(")","").strip()
    row[14] = handle_gb(row[10])[1].replace("-","").replace(" ","").replace("GB","").strip()
    row[10] = handle_gb(row[10])[0].strip()
    row[9] = handle_oem(row[10])[1].replace("Blackberry","RIM").replace("TMobile","T-Mobile").strip()
    row[15] = handle_addon(row[10])[1].strip()
    row[10] = handle_addon(row[10])[0].replace(" by","").replace("FREE","").strip()
    writer.writerow(row)
in_file.close()    
out_file.close()

Ich habe versucht, dieses Problem durch Initialisieren der rowVariablen auf zu lösen , 1aber es hat nicht funktioniert.

Bitte helfen Sie mir bei der Lösung dieses Problems.

Martijn Pieters
quelle

Antworten:

369

Ihre readerVariable ist iterierbar. Wenn Sie sie durchlaufen, rufen Sie die Zeilen ab.

Um ein Element vor Ihrer Schleife zu überspringen, rufen Sie einfach next(reader, None)den Rückgabewert auf und ignorieren Sie ihn.

Sie können Ihren Code auch ein wenig vereinfachen. Verwenden Sie die geöffneten Dateien als Kontextmanager, damit sie automatisch geschlossen werden:

with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
   reader = csv.reader(infile)
   next(reader, None)  # skip the headers
   writer = csv.writer(outfile)
   for row in reader:
       # process each row
       writer.writerow(row)

# no need to close, the files are closed automatically when you get to this point.

Wenn Sie den Header unverarbeitet in die Ausgabedatei schreiben möchten, ist dies ebenfalls einfach. Übergeben Sie die Ausgabe von next()an writer.writerow():

headers = next(reader, None)  # returns the headers or `None` if the input is empty
if headers:
    writer.writerow(headers)
Martijn Pieters
quelle
22
Eine Alternative ist auch auf den Einsatz for row in islice(reader, 1, None)- wenn auch weniger explizit als nextfür die meisten einfach für das Überspringen mehrere Kopfzeilen (oder immer nur bestimmte Stücke etc ...) ist es ganz praktisch Arbeitsplätze „ eine Zeile überspringen“
Jon Clements
Ich würde in Betracht ziehen,try: writer.write(next(reader))... except StopIteration: # handle empty reader
Jon Clements
@ JonClements: Vielleicht. Dies funktioniert gut genug, ohne über try:/ unterrichten zu müssen except:.
Martijn Pieters
1
@ JonClements: Vorteil der expliziten nextIteration ist, dass sie "kostenlos" ist. islicewürde den readerfür immer hinzugefügten (zugegebenermaßen sehr geringen) Overhead zu jeder Iteration einschließen. Das consumeRezept vonitertools kann verwendet werden, um viele Werte schnell zu überspringen, ohne der nachfolgenden Verwendung eine Umhüllung hinzuzufügen, falls die isliceein a startaber nein haben würde end, sodass der Overhead Ihnen nichts bringt.
ShadowRanger
120

Eine andere Möglichkeit, dies zu lösen, besteht darin, die DictReader-Klasse zu verwenden, die die Kopfzeile "überspringt" und damit die benannte Indizierung zulässt.

Geben Sie "foo.csv" wie folgt an:

FirstColumn,SecondColumn
asdf,1234
qwer,5678

Verwenden Sie DictReader wie folgt:

import csv
with open('foo.csv') as f:
    reader = csv.DictReader(f, delimiter=',')
    for row in reader:
        print(row['FirstColumn'])  # Access by column header instead of column number
        print(row['SecondColumn'])
Chad Zawistowski
quelle
21
Ich denke, dies ist die eigentliche Antwort, da die Frage ein Beispiel für ein XY-Problem zu sein scheint .
Marius Siuram
3
DictReader ist definitiv der richtige Weg
Javier Arias
4
Es ist wichtig zu beachten, dass dies nur funktioniert, wenn Sie den Parameter Feldnamen beim Erstellen des DictReader weglassen. Gemäß der Dokumentation: If the fieldnames parameter is omitted, the values in the first row of the file f will be used as the fieldnames.Siehe docs.python.org/2/library/csv.html
BuvinJ
7

Wenn row=1Sie dies tun , ändert sich nichts, da Sie dies nur mit den Ergebnissen der Schleife überschreiben.

Sie möchten next(reader)eine Zeile überspringen.

Katriel
quelle
Ich habe versucht, es zu ändern, for row in next(reader):aber es gibt mir IndexError: string index out of rangeFehler
Verwenden Sie es vor der for-Schleife: next(reader); for row in reader:....
dlazesz