22

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']
['', '']
...
4

4 に答える 4

42

何が起こっているのか、まあ、への呼び出し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ますが、文字ベースで反復する文字列を渡しているため、文字ごとに解析しています。これを修正する 1 つの方法は、一時ファイルを生成することです。反復可能オブジェクトを渡す必要があるだけです。

以下に注意してください。これは、リーダーにフィードする前に、文字列を行のリストに単純に分割します。

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]ます...

于 2012-08-27T06:39:29.117 に答える
7

これは完全に機能します:

import csv

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

最初のパラメータは次のcsv.readerとおりです。

イテレータ プロトコルをサポートし、次の() メソッドが呼び出されるたびに文字列を返す任意のオブジェクト

docsに従って、ファイルオブジェクトではなく文字列を渡しています。文字列は単一文字のリストとして動作するため、観察している動作です。

于 2012-08-27T06:10:26.690 に答える
5

単純な問題: csv.readerは入力に文字列を期待していませんでした。

簡単な解決策: 入力を次のように変更しますdata.splitlines()

csv リーダーは、一度に 1 行ずつ返す iterable を想定しています。残念ながら、文字列は一度に 1 文字ずつ繰り返します。この問題を解決するには、splitlines()を使用して文字列を行のリストに変換します。

reader = csv.reader(data.splitlines(), delimiter='\t')
for row in reader:
    print row
于 2012-08-27T06:43:10.167 に答える
1

おそらく、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

于 2012-08-27T06:09:00.403 に答える