Файл с разделителями табуляции с использованием csv.reader, не разграничивающий, где я ожидаю

Я пытаюсь просмотреть файл результатов выборов с разделителями табуляции, используя Python. Следующий код не работает, но когда я использую локальный файл с теми же результатами (закомментированная строка), он работает, как и ожидалось.

Единственное, о чем я могу думать, это какие-то заголовки или тип контента, который мне нужен для передачи URL-адреса, но я не могу понять это.

Почему это происходит?

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

Результат:

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

person foxyNinja7    schedule 27.08.2012    source источник


Ответы (4)


Итак, что происходит, вызов help может пролить некоторый свет.

>>> 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.

поэтому кажется, что csv.reader ожидает какой-то итератор, который вернет строку, но мы передаем строку, которая повторяется на основе char, поэтому ее синтаксический анализ символ за символом, один из способов исправить это - создать временный файл , но нам это не нужно, нам просто нужно передать любой итерируемый объект.

обратите внимание на следующее, которое просто разбивает строку на список строк, прежде чем она будет передана читателю.

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

это, кажется, работает.

Я также рекомендую использовать csv.DictReader, это очень полезно.

>>> 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'}

в основном он возвращает словарь для каждой строки, используя заголовок в качестве ключа, таким образом, нам не нужно отслеживать порядок, а вместо этого просто имя делает нас немного проще, т.е. row['Votes'] кажется более читаемым, чем row[4]...

person Samy Vilar    schedule 27.08.2012

Это отлично работает:

import csv

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

Первый параметр csv.reader должен быть:

любой объект, который поддерживает протокол итератора и возвращает строку каждый раз, когда вызывается его метод next()

согласно документации, и вы передаете строку, а не файловый объект. Строка ведет себя как список отдельных символов, следовательно, поведение, которое вы наблюдаете.

person daedalus    schedule 27.08.2012

Простая проблема: csv.reader не ожидал ввода строки.

Простое решение: измените ввод на: data.splitlines().

Читатель csv ожидает итерацию, которая возвращает строки по одной. Строка, к сожалению, повторяет символ за раз. Чтобы решить эту проблему, используйте splitlines(), чтобы преобразовать строку в список строк:

reader = csv.reader(data.splitlines(), delimiter='\t')
for row in reader:
    print row
person Raymond Hettinger    schedule 27.08.2012

Возможно, вы хотите понюхать диалект через csv API:

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

Это даст правильный вывод.

Смотрите также

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

person Andreas Jung    schedule 27.08.2012
comment
Оригинал на самом деле заключается в том, что вы передаете данные непосредственно конструктору reader() вместо дескриптора файла. - person Andreas Jung; 27.08.2012