【问题标题】:Windows to Linux script issues: "IndexError: list index out of range"Windows 到 Linux 脚本问题:“IndexError: list index out of range”
【发布时间】:2015-05-19 06:56:47
【问题描述】:

我有一个脚本 - 在 Windows 中完美运行,但是当我尝试在 Ubuntu 中运行它时,它吐出了错误消息:

IndexError: 列表索引超出范围。

这是一个非常简单的脚本:它导入CSV 文件,读取行,将每行中的第一项打印到列表中,使用set() 删除重复项,然后将这个新列表写入文件。

import csv, glob

for x in glob.glob("*raw_vcf.csv"):
   csv_f = open(x, "r")

data = [c for c in csv.reader(csv_f)]
frags_unique = []

def frag_list(vcf_data, uniquefrags):
    """ 
    User input: an imported .vcf file (='vcf_import'); an empty list
    (= 'uniquefrags').
    'frag_list' takes 'vcf_import', reads each row/list, taking the first item
    and attaching only unique values to 'uniquefrags', using the set() function.
    First row (header row) in 'vcf_data' is deleted; not needed.
    """
    del vcf_data[0]
    list_1 = []
    for row in vcf_data:
        list_1.append(row[0])
    for item in list(set(list_1)):
        uniquefrags.append(item)

frag_list(data, frags_unique)

out = open("output_unique_frags.txt","w")
for frags in frags_unique:
    out.write(frags+"\n")
out.close()

具体是模块中出现的错误:

Traceback (most recent call last):
  File "PRIME_unique_frags.py", line 50, in <module>
    frag_list(data, frags_unique)
  File "PRIME_unique_frags.py", line 46, in frag_list
    list_1.append(row[0])
IndexError: list index out of range

但老实说,我看不出它有什么问题,因为它可以在我的 Windows 操作系统上运行;尝试用不同的方式重写它,但没有成功。

一些样本输入数据(“*_raw_vcf.csv”):

A,B,C,D,E
1,2,3,4,5
1,5,4,3,2
2,3,4,5,6
2,3,4,7,8
3,4,5,6,7

理论上应该(并且在 Windows 中)应该生成一个文件(“output_unique_frags.txt”;A 列中的唯一值):

1
2
3

【问题讨论】:

  • 使用调试器或打印语句来找出 Linux 上 row 的值是什么。然后你可以确定为什么你会得到 IndexError。不过,我认为@warvariuc 的回答非常接近主题
  • 在 frag_unique=[] 之后使用 print 语句,例如 print csv_f 来查看正在读取的 csv 并在 del vcf_data[0] 之后使用 print del vcf_data 查看并说出正在打印的内容

标签: python linux windows csv ubuntu


【解决方案1】:

Traceback 是说row 没有元素[0],所以它是一个空列表。这表明在 Ubuntu 系统上,阅读器为每一行返回一个空列表。

看看csv docs;您可以在设置阅读器时指定方言。我会说 Ubuntu 系统上的阅读器正在寻找与文件中不同的分隔符。

顺便说一句:上面代码的缩进是否正确?如果是这样,那里会发生一些奇怪的事情,例如:

for x in glob.glob("*raw_vcf.csv"):
   csv_f = open(x, "r")

如果有多个 .csv 文件,您只会得到最后一个。

【讨论】:

  • 1 你只会得到最后一个
【解决方案2】:

看起来行尾不是罪魁祸首:

Python 2.7.8 (default, Oct 20 2014, 15:05:19) 
[GCC 4.9.1] on linux2
>>> a = """A,B,C,D,E
... 1,2,3,4,5
... 1,5,4,3,2
... 2,3,4,5,6
... 2,3,4,7,8
... 3,4,5,6,7"""
>>> with open('1.csv', 'w') as f:
...     f.write(a.replace('\n', '\r\n'))
... 
>>> import csv
>>> list(csv.reader(open('1.csv', "r")))
[['A', 'B', 'C', 'D', 'E'], ['1', '2', '3', '4', '5'], ['1', '5', '4', '3', '2'], ['2', '3', '4', '5', '6'], ['2', '3', '4', '7', '8'], ['3', '4', '5', '6', '7']]

另一个猜测是问题出在这里:

for x in glob.glob("*raw_vcf.csv"):
   csv_f = open(x, "r")

这将打开带有掩码"*raw_vcf.csv" 的目录中的最后一个文件。我猜你有不止一个文件要处理。在 Windows 上你得到一个文件,在 Linux 上它可能是另一个格式错误的文件。

您应该调试问题。打印用于打开文件的文件名。

旧答案:

docs say:

注意阅读器被硬编码为将'\r''\n' 识别为 行尾,并忽略lineterminator。这种行为可能会改变 未来。

我想 CSV 文件是在 Windows 中创建的,以 \r\n 作为行终止符。所以Linux下的读者会因此发现空行。

解决方案(未经测试,取自here):

csv_f = open(filename, 'rtU')

【讨论】:

    【解决方案3】:

    大家好,感谢反馈!


    简单地回应一些 cmets:我非常确定“*raw_vcf.csv”只有一次出现,这样,

    for x in glob.glob("*raw_vcf.csv"):
       csv_f = open(x, "r")
    

    只会提取一个文件 - 我对此进行了测试以确保它可以正常工作。


    解决方案

    在关于列表为空的建议之后,我检查了它:

    当我要求打印 row[0] (用于数据中的行)时,这并不明显,但是在打印列表时,我注意到数据文件中有一个额外的 ENTER 被读取为空行(列表中的最后一个元素:'[]')。这就是把它扔掉的原因,因为 .append() 不会添加任何内容。

    再次感谢 cmets。事后看来,这是一个简单的问题,但由于我对 Python 还是很陌生,解释行话可能有点挑战。感谢所有提供建议并帮助我下次学习的人。

    【讨论】:

    • 啊,是的,最后不经意的空白行 - 我自己打了这个。很高兴你把它整理好,并在这个过程中学到了一些东西......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 2015-02-11
    • 2018-02-08
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多