2013-04-13 3 views
0

Я - кодер noob, столкнувшийся с проблемой при разборе файла csv с помощью модуля csv Python. Проблема в том, что мой вывод говорит, что значения полей в строке «None» для всех, кроме первого поля.Python csv DictReader возвращает «None» для значений полей; Есть идеи?

Вот первая строка в уродливой CSV файл, который я пытаюсь разобрать (остальные строки в том же формате):

0,213726,NORTH FORK SLATE CREEK,CAMPGROUND,North Fork Slate Creek Campground | Idaho |  Public Lands Information Center | Recreation Search, http://www.publiclands.org/explore/site.php?plicstate=ID&id=2268,NA,NA,NA,NA,(208)839-2211,"Nez Perce National Forest Operating Days: 305<br>Total Capacity: 25<br> 

5 campsites at the confluence of Slate Creek and its North Fork. A number of trails form loops in the area. These are open to most traffic, including trail bikes.","From Slate Creek, go 8 miles east on Forest Road 354.",NA,http://www.publiclands.org/explore/reg_nat_forest.php?region=7&forest_name=Nez%20Perce%20National%20Forest,NA,NA,NA,45.6,-116.1,NA,N,0,1103,2058 

Вот код, который я написал для разбора CSV-файла (это Безразлично Не работайте правильно!)

import csv 

#READER SETTINGS 
f_path = '/Users/foo' 
f_handler = open(f_path, 'rU').read().replace('\n',' ') 
my_fieldnames = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7', 
'col8', 'col9', 'col10', 'col11', 'col12', 'col13', 'col14', 'col15', 
'col16', 'col17', 'col18', 'col19', 'col20', 'col21', 'col22', 'col23', 
'col24','col25'] 
f_reader = csv.DictReader(f_handler, fieldnames=my_fieldnames, delimiter=',', dialect=csv.excel) 

#NOW I TRY TO PARSE THE CSV FILE 
i = 0 
for row in f_reader: 
    print "my first row was %s" % row 
    i = i + 1 
    if i > 0: 
     break 

И вот вывод. В нем говорится, что все поля, кроме первого, пустые, и я не знаю, почему! Любые предложения будут высоко ценится.

my first row was {'col14': None, 'col15': None, 'col16': None, 
'col17': None, 'col10': None, 'col11': None, 'col12': None, 
'col13': None, 'col18': None, 'col19': None, 'col2': None, 'col8': None, 
'col9': None, 'col6': None, 'col7': None, 'col4': None, 'col5': None, 
'col3': None, 'col1': '0', 'col25': None, 'col24': None, 
'col21': None, 'col20': None, 'col23': None, 'col22': None} 

ответ

3

Попробуйте это:

#!/usr/bin/env python 

import csv 

my_fieldnames = ['col' + str(i) for i in range(1,26)] 

with open('input.csv', 'rb') as csvfile: 
    my_reader = csv.DictReader(csvfile, fieldnames=my_fieldnames, 
           delimiter=',', dialect=csv.excel, 
           quoting=csv.QUOTE_NONE) 

    for row in my_reader: 
     for k,v in row.iteritems(): 
      print k, v 

выхода для первой строки ввода (помните, что словари неупорядоченные):

col14 None 
col15 None 
col16 None 
col17 None 
col10 NA 
col11 (208)839-2211 
col12 "Nez Perce National Forest Operating Days: 305<br>Total Capacity: 25<br> 
col13 None 
col18 None 
col19 None 
col8 NA 
col9 NA 
col6 http://www.publiclands.org/explore/site.php?plicstate=ID&id=2268 
col7 NA 
col4 CAMPGROUND 
col5 North Fork Slate Creek Campground | Idaho |  Public Lands Information Center | Recreation Search 
col2 213726 
col3 NORTH FORK SLATE CREEK 
col1 0 
col25 None 
col24 None 
col21 None 
col20 None 
col23 None 
col22 None 
0

Когда вы делаете:

f_handler = open(f_path, 'rU').read().replace('\n',' ') 

вы удаляете всю новую строку s, так как диалект csv.excel обнаруживает новые строки. Поскольку файл имеет только одну строку, он будет возвращаться только один раз.

Кроме того, вы делаете:

if i > 0: 
    break 

который завершает ваш цикл после первой итерации.

О том, почему они пусты, по умолчанию restval имеет значение None (см. http://docs.python.org/3.2/library/csv.html), поэтому ключи, вероятно, не совпадают. Не пытайтесь включить аргумент fieldnames, и вы, вероятно, увидите, что ваши ключи на этом диалекте совпадают с строками «col2», «col3» или тому подобное.

Милый маленький обертка я использую: использование

def iter_trim(dict_iter): 
#return (dict(zip([k.strip(" \t\n\r") for k in row.keys()], [v.strip(" \t\n\r") for v in row.values()])) for row in dict_iter) 
for row in dict_iter: 
    try: 
     d = dict(zip([k.strip(" \t\n\r") for k in row.keys()], [v.strip(" \t\n\r") for v in row.values()])) 
     yield d 
    except: 
     print "row error:" 
     print row 

Пример:

def csv_iter(filename): 
    csv_fp = open(filename) 
    guess_dialect = csv.Sniffer().sniff(csv_fp.read(16384)) 
    csv_fp.seek(0) 
    csv_reader = csv.DictReader(csv_fp,dialect=guess_dialect) 
    return iter_trim(csv_reader) 
for row in csv_iter("some-file.csv"): 
    # do something... 
    print row 
0

вселенной вещей, что различные системы программного обеспечения вызова CSV зависит многое. К счастью, отличный CSV-модуль Python отлично справляется с этими деталями, поэтому вам не нужно обращаться с этими вещами вручную.

Подчеркнем, что некоторые вещи использовали ответ @ metaperture, но не объяснили: вы можете избежать всех догадок, прочитав CSV-файл в Python, автоматически обнаруживая диалект. Как только вы пригвоздите эту часть, не так много, что может пойти не так.

Позвольте мне дать вам простой пример:

import csv 

    with open(filename, 'rb') as csvfile: 
     dialect = csv.Sniffer().sniff(csvfile.read(10024)) 
     csvfile.seek(0) 
     qreader = csv.reader(csvfile, dialect) 
     cnt = 0 
     for item in qreader: 
      if cnt >0: 
       #process your data 
      else: 
       #the header of the csv file (field names)  
      cnt = cnt + 1 
Смежные вопросы