2009-08-14 4 views
8

Ich versuche, eine CSV-Datei mit Pythons csv Modul zu analysieren (speziell die DictReader Klasse). Gibt es einen pythonischen Weg, um leere oder fehlende Felder zu erkennen und einen Fehler zu erzeugen?Wie erkenne ich fehlende Felder in einer CSV-Datei auf pythonische Weise?

Hier ist eine Beispieldatei mit den folgenden Überschriften: NAME, LABEL, VALUE

foo,bar,baz 
yes,no 
x,y,z 

Beim Parsen, würde ich die zweite Zeile wie einen Fehler zu werfen, da es mit dem VALUE-Feld fehlt.

Hier ist ein Code-Schnipsel, die zeigt, wie ich näher dies (die hartcodierte Strings außer Acht lassen ... sie sind der Kürze halber nur vorhanden):

import csv 

HEADERS = ["name", "label", "value" ] 
fileH = open('configFile') 
reader = csv.DictReader(fileH, HEADERS) 

for row in reader: 
    if row["name"] is None or row["name"] == "": 
     # raise Error 
    if row["label"] is None or row["label"] == "": 
     # raise Error 
    ... 
fileH.close() 

Gibt es eine saubere Art und Weise für die Überprüfung von Felder in der CSV-Datei w/out mit einer Reihe von if Aussagen? Wenn ich weitere Felder hinzufügen muss, brauche ich auch mehr Konditionalitätsregeln, die ich möglichst vermeiden möchte.

Antwort

14
if any(row[key] in (None, "") for key in row): 
    # raise error 

bearbeiten: Noch besser:

if any(val in (None, "") for val in row.itervalues()): 
    # raise error 
+0

Süße Pythonic Weg! –

+0

Diese Methode ist mit dem Verhalten von csv.DictReader ziemlich inkompatibel. Es durchläuft alle Schlüssel in der Zeile, auch wenn einige davon vom DictReader verworfen werden, da sie in HEADERS nicht explizit erwähnt wurden. Mehr hier: http://docs.python.org/library/csv.html#csv.DictReader – Triptych

+0

@Triptych: Es gibt höchstens einen solchen zusätzlichen Schlüssel (der Wert, der als Restkey an den Konstruktor übergeben wird). Ich sehe das Problem damit nicht. – balpha

1

So ähnlich?

... 
for row in reader: 
    for column, value in row.items(): 
     if value is None or value == "": 
      # raise Error, using value of column to say which field is missing 

Möglicherweise können Sie anstelle des expliziteren Tests, den Sie angegeben haben, 'if not value:' als Test verwenden.

2

Da None und leere Strings beide bewerten zu False, sollten Sie dies berücksichtigen:

for row in reader: 
    for header in HEADERS: 
     if not row[header]: 
      # raise error 

Beachten Sie, dass, im Gegensatz zu einigen anderen Antworten Sie haben weiterhin die Möglichkeit, einen informativen, headerspezifischen Fehler zu melden.

+0

Dies führt zu falschen positiven Ergebnissen, wenn Sie numerische 0-Werte in einer beliebigen Spalte haben und "zotieren" auf "csv.QUOTE_NONNUMERIC" gesetzt ist. –

1

Dieser Code enthält für jede Zeile eine Liste von Feldnamen, die für diese Zeile nicht vorhanden (oder leer) sind. Sie könnten dann eine ausführlichere Ausnahme angeben, z. B. "Fehlende Felder: foo, baz".

def missing(row): 
    return [h for h in HEADERS if not row.get(h)] 

for row in reader: 
    m = missing(row) 
    if missing: 
     # raise exception with list of missing field names 
0

Wenn Sie matplotlib.mlab.csv2rec verwenden, speichert es bereits den Inhalt der Datei in ein Array und einen Fehler auslösen, wenn einer der Werte fehlt.

Das Problem besteht darin, dass es keine einfache Möglichkeit gibt, dieses Verhalten anzupassen oder einen Standardwert im Falle fehlender Zeilen anzugeben. Außerdem ist die Fehlermeldung nicht sehr erklärend (könnte nützlich sein, um hier einen Fehlerbericht zu posten).

p.s. Da csv2rec den Inhalt der Datei in einen numply-Datensatz speichert, ist es einfacher, die Werte gleich None zu erhalten.

Verwandte Themen