Написание с помощью встроенного в Python модуля .csv

[Обратите внимание, что это вопрос, отличный от уже отвеченного Как заменить столбец с помощью встроенного в Python модуля записи .csv?]

Мне нужно выполнить поиск и замену (для одного столбца URL-адресов) в огромном файле Excel .csv. Поскольку я только начинаю изучать язык сценариев, я решил попробовать реализовать решение на python.

У меня возникают проблемы, когда я пытаюсь выполнить обратную запись в файл .csv после внесения изменений в содержимое записи. Я прочитал официальную документацию по модулю csv о том, как использовать средство записи, но нет примера, который охватывает этот случай. В частности, я пытаюсь выполнить операции чтения, замены и записи в одном цикле. Однако нельзя использовать одну и ту же ссылку на «строку» как в аргументе цикла for, так и в качестве параметра для write.writerow(). Итак, как только я внес изменения в цикл for, как я должен выполнить обратную запись в файл?

изменить: я реализовал предложения С. Лотта и Джимми, результат тот же.

редактирование №2: я добавил "rb" и "wb" в функции open() по предложению С. Лотта.

import csv

#filename = 'C:/Documents and Settings/username/My Documents/PALTemplateData.xls'

csvfile = open("PALTemplateData.csv","rb")
csvout = open("PALTemplateDataOUT.csv","wb")
reader = csv.reader(csvfile)
writer = csv.writer(csvout)

changed = 0;

for row in reader:
    row[-1] = row[-1].replace('/?', '?')
    writer.writerow(row)                  #this is the line that's causing issues
    changed=changed+1

print('Total URLs changed:', changed)

Изменить: Для справки, это новая полная трассировка от интерпретатора:

Traceback (most recent call last):
  File "C:\Documents and Settings\g41092\My Documents\palScript.py", line 13, in <module>
    for row in reader:
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

person ignorantslut    schedule 19.06.2009    source источник


Ответы (3)


Вы не можете читать и записывать один и тот же файл.

source = open("PALTemplateData.csv","rb")
reader = csv.reader(source , dialect)

target = open("AnotherFile.csv","wb")
writer = csv.writer(target , dialect)

Обычный подход ко ВСЕМ манипуляциям с файлами заключается в создании модифицированной КОПИИ исходного файла. Не пытайтесь обновлять файлы на месте. Это просто плохой план.


Изменить

В линиях

source = open("PALTemplateData.csv","rb")

target = open("AnotherFile.csv","wb")

«rb» и «wb» абсолютно необходимы. Каждый раз, когда вы их игнорируете, вы открываете файл для чтения в неправильном формате.

Вы должны использовать «rb» для чтения файла .CSV. В Python 2.x нет выбора. В Python 3.x вы можете опустить это, но явно использовать «r», чтобы было понятно.

Вы должны использовать «wb» для записи файла .CSV. В Python 2.x нет выбора. В Python 3.x вы должны использовать «w».


Изменить

Похоже, вы используете Python3. Вам нужно убрать «b» из «rb» и «wb».

Прочитайте это: http://docs.python.org/3.0/library/functions.html#open

person S.Lott    schedule 19.06.2009
comment
Хорошо, я тоже позаботился об этом вопросе. Похоже, мы приближаемся... Трассировка стала короче :) - person ignorantslut; 20.06.2009
comment
Однако теперь, когда я думаю об этом, до того, как я попытался выполнить обратную запись в файл (то есть, когда я все еще работал над поиском нужного столбца в .csv), сценарий отлично работал без rb. - person ignorantslut; 20.06.2009
comment
rb и wb абсолютно необходимы.: не в Python 3. Там вы должны вызвать open() с новой строкой = ''. - person Miles; 20.06.2009
comment
Удаление 'b' из rb и wb помогло... Всем спасибо! - person ignorantslut; 22.06.2009

Открытие файлов csv в виде двоичных файлов просто неправильно. CSV — это обычные текстовые файлы, поэтому вам нужно открыть их с помощью

source = open("PALTemplateData.csv","r")
target = open("AnotherFile.csv","w")

Ошибка

_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

приходит, потому что вы открываете их в двоичном режиме.

Когда я открывал excel csv с помощью python, я использовал что-то вроде:

try:    # checking if file exists
    f = csv.reader(open(filepath, "r", encoding="cp1250"), delimiter=";", quotechar='"')
except IOError:
    f = []

for record in f:
    # do something with record

и это работало довольно быстро (я открывал два CSV-файла размером около 10 МБ каждый, хотя я делал это с Python 2.6, а не с версией 3.0).

Есть несколько рабочих модулей для работы с CSV-файлами Excel из Python — pyExcelerator — один из них.

person zeroDivisible    schedule 22.06.2009
comment
(1) Совет по открытию файла совершенно некорректен. Для Python 2.x используйте rb или wb в зависимости от ситуации. Для Python 3.x для чтения укажите newline='' (2) Я не понимаю Есть несколько рабочих модулей для работы с файлами excel csv из python. Есть один модуль csv. Какова актуальность pyExcelerator?? - person John Machin; 23.06.2009
comment
Джон, я на 100% уверен, что когда я работал с файлами csv с python 2.6, я открывал их в текстовом, а не в бинарном режиме. Я открыл, попытался открыть один сейчас в python 2.6.2 - это сработало как шарм. Английский — мой второй язык, поэтому мои посты/комментарии обычно звучат так, как будто их написал пьяный подросток. Что я имел в виду под pyExcelerator, так это то, что есть несколько модулей, разработанных специально для работы с файлами csv - я не писал, что эти модули включены в стандартный дистрибутив. Здоровья, приятель. - person zeroDivisible; 23.06.2009
comment
(1) 2.x открытие в текстовом режиме не будет работать должным образом, если в ваши данные встроены новые строки. В мануале написано открывать в бинарном режиме. Просто сделай это! (2) pyExcelerator не читает и не записывает CSV-файлы; снова спрашиваю: в чем актуальность pyExcelerator??? - person John Machin; 25.06.2009

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

person Jimmy    schedule 19.06.2009