【问题标题】:What's wrong with this python program working on .csv?这个在 .csv 上运行的 python 程序有什么问题?
【发布时间】:2011-12-12 19:23:18
【问题描述】:

我有一个包含字符串列表的文本文件。

我想在 .csv 文件中搜索以这些字符串开头的行并将它们放入新的 .csv 文件中。

在本例中,文本文件名为“output.txt”,原始 .csv 为“input.csv”,新的 .csv 文件为“corrected.csv”。

代码:

import csv

file = open('output.txt')
while 1:
    line = file.readline()
    writer = csv.writer(open('corrected.csv','wb'), dialect = 'excel')
    for row in csv.reader('input.csv'):
        if not row[0].startswith(line):
            writer.writerow(row)
    writer.close()
    if not line:
        break
    pass

错误:

Traceback (most recent call last):
File "C:\Python32\Sample Program\csvParser.py", line 9, in <module>
writer.writerow(row)
TypeError: 'str' does not support the buffer interface`

新错误:

Traceback (most recent call last):
File "C:\Python32\Sample Program\csvParser.py", line 12, in <module>
for row in reader:
_csv.Error: line contains NULL byte

问题是 CSV 文件是用制表符而不是逗号保存的,现在的新问题如下:

Traceback (most recent call last):
  File "C:\Python32\Sample Program\csvParser.py", line 13, in <module>
    if row[0] not in lines:
IndexError: list index out of range

CSV 文件有 500 多个数据条目...这有什么不同吗?

【问题讨论】:

标签: python csv


【解决方案1】:

如果您查看documentation,这就是reader 的初始化方式:

spamReader = csv.reader(open('eggs.csv', 'r'), ...

注意open('eggs.csv, 'rb')。您没有在9 行中传递file 句柄,因此str 被视为文件句柄并抛出错误。

9 行替换为:

csv.reader(open('input.csv', 'r', newline = ''))

【讨论】:

  • OP 使用的是 Python 3.2,它没有二进制模式要求。文档说要这样打开文件:open('input.csv', 'r', newline='')。请参阅 docs.python.org/py3k/library/csv.html。
  • 好点。也许 OP 会偶然发现您的评论,但现在,我将其编辑到代码中。
【解决方案2】:

csv.reader 无法打开文件,它需要一个文件对象。更好的解决方案是:

import csv

lines = []
with open('output.txt', 'r') as f:
    for line in f.readlines():
        lines.append(line[:-1])

with open('corrected.csv','w') as correct:
    writer = csv.writer(correct, dialect = 'excel')
    with open('input.csv', 'r') as mycsv:
        reader = csv.reader(mycsv)
        for row in reader:
            if row[0] not in lines:
                writer.writerow(row)

【讨论】:

  • Traceback (most recent call last): File "C:\Python32\Sample Program\csvParser.py", line 12, in &lt;module&gt; for row in reader: _csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
  • @JamesRoseman 呃,没有。 open 语句中包含用于读取二进制模式的“rb”。我开始怀疑您的数据文件在某种程度上已损坏。正如 Blender 所指出的,csv 库使用二进制文件句柄。
  • for line in f.readlines(): lines.append(line) 是一种罗嗦的说法 lines = f.readlines()
  • @Spencer Rathbun 这是我收到的错误信息,不是我的批评。我非常感谢在我几乎没有经验的问题上提供的帮助,所以谢谢。我很肯定数据没有损坏,但可能是它的格式化方式会导致这种类型的错误?
  • @Spencer Rathbun:OP 使用的是 Python 3.2,它没有二进制模式要求。文档说要这样打开文件:open('input.csv', 'r', newline='')。请参阅 docs.python.org/py3k/library/csv.html。
【解决方案3】:

你的最新问题:

    if row[0] not in lines:
IndexError: list index out of range

错误消息提到了一个列表索引。
它只能谈论一个列表索引:0
如果0 超出范围,则len(row) 必须为零。
如果len(row) 为零,则输入文件中的对应行必须为空。
如果输入文件中有一行是空的,你想做什么:

(a) 完全忽略输入行?
(b) 引发一个(致命的)错误?
(c) 在某处记录错误消息并继续?
(d) 别的东西?

【讨论】:

    【解决方案4】:

    试试这个

    import csv
    import cStringIO
    
    file = open('output.txt') 
    while True:     
        line = file.readline()
        buf = cStringIO.StringIO()    
        writer = csv.writer(buf, dialect = 'excel')     
        for row in csv.reader(open('input.csv')):         
            if not row[0].startswith(line):             
                writer.writerow(row)     
        writer.close()
        output = open('corrected.csv', 'wb')
        output.write(buf.getvalue())    
        if not line:         
            break            
        pass
    

    根据我的经验,在整个过程中使用cStringIO 缓冲区,然后将整个缓冲区转储到文件中会更快。

    【讨论】:

    • -1。 cStringIO 是一个毫无意义的复杂问题。问题不在于他的代码太慢。像这样过早的优化是浪费时间。
    猜你喜欢
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多