Проблемы с Python CSV DictReader / Writer
Вопрос
Я пытаюсь извлечь несколько строк из CSV-файла и записать их в другой, но у меня возникают некоторые проблемы.
import csv
f = open("my_csv_file.csv", "r")
r = csv.DictReader(f, delimiter=',')
fieldnames = r.fieldnames
target = open("united.csv", 'w')
w = csv.DictWriter(united, fieldnames=fieldnames)
while True:
try:
row = r.next()
if r.line_num <= 2: #first two rows don't matter
continue
else:
w.writerow(row)
except StopIteration:
break
f.close()
target.close()
Запустив это, я получаю следующую ошибку:
Traceback (most recent call last):
File "unify.py", line 16, in <module>
w.writerow(row)
File "C:\Program Files\Python25\lib\csv.py", line 12
return self.writer.writerow(self._dict_to_list(row
File "C:\Program Files\Python25\lib\csv.py", line 12
if k not in self.fieldnames:
TypeError: argument of type 'NoneType' is not iterable
Не совсем уверен, в чем я не прав.
Решение
Я тоже не знаю, но поскольку все, что вы делаете, это копирование строк из одного файла в другой, почему вы вообще беспокоитесь о csv
? Почему не что-то вроде:
f = open("my_csv_file.csv", "r")
target = open("united.csv", 'w')
f.readline()
f.readline()
for line in f:
target.write(line)
Другие советы
Чтобы устранить путаницу, связанную с ошибкой:ты понимаешь это, потому что r.fieldnames
устанавливается только после первого чтения из входного файла с помощью r
.Отсюда и то, как вы это написали, fieldnames
всегда будет инициализирован следующим образом None
.
Вы можете инициализировать w = csv.DictWriter(united, fieldnames=fieldnames)
с r.fieldnames
только после того, как вы прочтете первую строку из r
, что означает, что вам придется реструктурировать свой код.
Это поведение задокументировано в Документация по стандартной библиотеке Python
Объекты DictReader имеют следующий общедоступный атрибут:
csvreader.имена полей
Если этот атрибут не передан в качестве параметра при создании объекта, он инициализируется при первом обращении или при считывании первой записи из файла.
Что касается исключения, оно выглядит следующим образом:
w = csv.DictWriter(united, fieldnames=fieldnames)
должно быть
w = csv.DictWriter(target, fieldnames=fieldnames)
Причина, по которой вы получаете ошибку, - это, скорее всего, то, что ваш исходный файл CSV (my_csv_file.csv) не имеет строки заголовка. Поэтому, когда вы создаете объект чтения, его поле fieldnames устанавливается в None
.
Когда вы пытаетесь записать строку, используя программу записи, она сначала проверяет, нет ли в dict ключей, которых нет в списке известных полей. Поскольку для fieldnames
установлено значение None
, попытка разыменования имени ключа вызывает исключение.