2012-08-27 3 views
13

Ich versuche, eine Tab-getrennte Datei von Wahlergebnissen mit Python zu durchlaufen. Der folgende Code funktioniert nicht, aber wenn ich eine lokale Datei mit den gleichen Ergebnissen (die auskommentierte Zeile) verwende, funktioniert es wie erwartet.Tab-getrennte Datei mit csv.reader, die nicht begrenzt, wo ich es erwarte

Das einzige, was ich denken kann, ist einige Header oder Inhaltstyp Ich muss die URL übergeben, aber ich kann es nicht herausfinden.

Warum passiert das?

import csv 
import requests 

r = requests.get('http://vote.wa.gov/results/current/export/MediaResults.txt') 
data = r.text 
#data = open('data/MediaResults.txt', 'r') 
reader = csv.reader(data, delimiter='\t') 
for row in reader: 
    print row 

Ergebnisse in:

... 
['', ''] 
['', ''] 
['2'] 
['3'] 
['1'] 
['1'] 
['8'] 
['', ''] 
['D'] 
['a'] 
['v'] 
['i'] 
['d'] 
[' '] 
['F'] 
['r'] 
['a'] 
['z'] 
['i'] 
['e'] 
['', ''] 
... 

Antwort

29

Also was passiert, na ja, ein Anruf an help kann etwas Licht vergießen.

>>> help(csv.reader) 
reader(...) 
    csv_reader = reader(iterable [, dialect='excel'] 
          [optional keyword args]) 
     for row in csv_reader: 
      process(row) 

    The "iterable" argument can be any object that returns a line 
    of input for each iteration, such as a file object or a list. The 
    optional "dialect" parameter is discussed below. The function 
    also accepts optional keyword arguments which override settings 
    provided by the dialect. 

so scheint es, dass csv.reader einen Iterator irgendeiner Art erwartet, die eine Linie zurückkehren, aber wir sind vorbei eine Zeichenkette, die eine Iteration auf einem char Basen, die warum zeichenweise seine Analyse ist, besteht eine Möglichkeit, dies zu beheben wäre eine temporäre Datei zu erzeugen, aber wir müssen nicht, müssen wir nur irgendein iterables Objekt übergeben.

beachten Sie folgendes, das die Zeichenfolge einfach in eine Liste von Zeilen aufteilt, bevor sie dem Leser zugeführt wird.

import csv 
import requests 

r = requests.get('http://vote.wa.gov/results/current/export/MediaResults.txt') 
data = r.text 
reader = csv.reader(data.splitlines(), delimiter='\t') 
for row in reader: 
    print row 

das scheint zu funktionieren.

Ich empfehle auch csv.DictReader ist es recht nützlich.

>>> reader = csv.DictReader(data.splitlines(), delimiter='\t') 
>>> for row in reader: 
...  print row 
{'Votes': '417141', 'BallotName': 'Michael Baumgartner', 'RaceID': '2', 'RaceName': 'U.S. Senator', 'PartyName': '(Prefers Republican Party)', 'TotalBallotsCastByRace': '1387059', 'RaceJurisdictionTypeName': 'Federal', 'BallotID': '23036'} 
{'Votes': '15005', 'BallotName': 'Will Baker', 'RaceID': '2', 'RaceName': 'U.S. Senator', 'PartyName': '(Prefers Reform Party)', 'TotalBallotsCastByRace': '1387059', 'RaceJurisdictionTypeName': 'Federal', 'BallotID': '27435'} 

im Grunde gibt es ein Wörterbuch für jede Zeile, die Kopfzeile als Schlüssel, so brauchen wir nicht den Überblick über die Ordnung zu halten, sondern nur der Name macht ein bisschen leichter für uns, dh row['Votes'] scheint besser lesbar als row[4] ...

+0

Ich hätte das selbst herausfinden müssen. Vielen Dank. – foxyNinja7

1

Vielleicht möchten Sie den Dialekt durch die csv-API schnuppern:

csvfile = open("example.csv", "rb") 
dialect = csv.Sniffer().sniff(csvfile.read(1024)) 
csvfile.seek(0) 
reader = csv.reader(csvfile, dialect) 

Dies wird die richtige Ausgabe erzeugen.

Siehe auch

http://docs.python.org/library/csv.html#csv.Sniffer

+0

Das Original ist eigentlich, dass Sie die Daten direkt anstelle von Datei-Handle für den Leser() Konstruktor übergeben. –

3

Das funktioniert perfekt:

import csv 

reader = csv.reader(open('./MediaResults.txt'), 
        delimiter='\t') 
for row in reader: 
    print row 

Der erste Parameter für csv.reader sein sollte:

jedes Objekt, das das Protokoll Iterator unterstützt und liefert ein String jedes Mal seine nächste() -Methode

genannt

per the docs und Sie übergeben eine Zeichenfolge, kein Dateiobjekt. Eine Zeichenfolge verhält sich wie eine Liste einzelner Zeichen, daher das Verhalten, das Sie beobachten.

4

einfaches Problem: Die csv.reader hat keinen String für seine Eingabe erwarten.

Einfache Lösung: Ändern Sie den Eingang in: data.splitlines().

Der CSV-Reader erwartet ein iterables, das Zeilen einzeln zurückgibt. Ein String iteriert leider immer nur einen Charakter. Um das Problem zu lösen, verwendet Teilungslinien() die Zeichenfolge in eine Liste von Zeilen zu drehen:

reader = csv.reader(data.splitlines(), delimiter='\t') 
for row in reader: 
    print row 
Verwandte Themen