Запись со встроенным модулем Python .csv - PullRequest
7 голосов
/ 20 июня 2009

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

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

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

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

edit # 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)

edit: Для справки: new full traceback от интерпретатора:

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?)

Ответы [ 3 ]

10 голосов
/ 20 июня 2009

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

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

4 голосов
/ 22 июня 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).

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

2 голосов
/ 20 июня 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...