【问题标题】:Python: Using str.split and getting list index out of rangePython:使用 str.split 并使列表索引超出范围
【发布时间】:2025-11-30 23:05:01
【问题描述】:

我刚开始使用 python 并试图将我的一些 R 代码转换为 python。任务比较简单;我有许多带有变量名(在本例中为单元格行)和值(IC50)的 csv 文件。我需要提取所有文件之间共享的所有变量及其值。其中一些文件共享保存变量,但格式不同。例如,在某些文件中,变量只是“Cell_line”,而在其他文件中,它是 MEL:Cell_line。因此,首先要进行直接字符串比较,我需要将它们格式化为相同,因此我尝试使用 str.split() 来这样做。可能有更好的方法来做到这一点,但现在我使用以下代码:

import csv
import os
# Change working directory
os.chdir("/Users/joshuamannheimer/downloads")
file_name="NCI60_Bleomycin.csv" 
with open(file_name) as csvfile:
    NCI_data=csv.reader(csvfile, delimiter=',')
    alldata={}
    for row in NCI_data:
        name_str=row[0]
        splt=name_str.split(':')
        n_name=splt[1]
        alldata[n_name]=row

[1] name_str.split 返回一个长度为 2 的列表。由于我想要的部分在“:”之后,我想要第二个元素,它应该被索引为 splt[1],因为 splt[0] 是 python 中的第一个。但是,当我运行代码时,我收到此错误消息“IndexError: list index out of range” 我正在尝试长度为 2 的列表中的第二个元素,因此我不知道为什么它超出了范围。任何帮助或建议将不胜感激。

【问题讨论】:

  • 你确定最多只有一个:吗?
  • 它应该适用于"MEL:Cell_line";它会在"Cell_line" 上失败,因为它只有splt[0]。您可以使用splt[-1] 始终获取最后一个元素,无论有多少。

标签: python indexing string-split


【解决方案1】:

我很确定有些行中name_str 没有:。在您自己的示例中,如果name_strCell_line,它将失败。

如果您确定 name_str (at max) 中只有 1 个 : ,或者如果有多个 : 您想选择最后一个,而不是 splt[1] ,您应该使用-splt[-1]。 -1 索引将采用列表中的最后一个元素(除非它为空)。

【讨论】:

    【解决方案2】:

    简单的答案是,有时数据不符合您编写此代码时假定的规范(即有一个冒号和两个字段)。

    解决这个问题的最简单方法是添加一个 if 块 if len(splot)==2: 并在该块中执行后续行。

    或者,添加else: 并打印不那么规范的行或将它们保存在某个地方以便您进行诊断。

    像这样:

    import csv
    import os
    # Change working directory
    os.chdir("/Users/joshuamannheimer/downloads")
    file_name="NCI60_Bleomycin.csv" 
    with open(file_name) as csvfile:
        NCI_data=csv.reader(csvfile, delimiter=',')
        alldata={}
        for row in NCI_data:
            name_str=row[0]
            splt=name_str.split(':')
            if len(splt)==2: 
                 n_name=splt[1]
                 alldata[n_name]=row
            else:
                 print "invalid name: "+name_str
    

    或者,您可以使用try/except,在这种情况下更健壮一些,因为我们可以在任何地方处理 IndexError,在row[0]split[1] 中,使用一个异常处理程序,而我们没有必须指定:分割字段的长度应该是2。

    此外,我们可以在拆分之前明确检查是否确实存在:,并适当地分配名称。

    import csv
    import os
    # Change working directory
    os.chdir("/Users/joshuamannheimer/downloads")
    file_name="NCI60_Bleomycin.csv" 
    with open(file_name) as csvfile:
        NCI_data=csv.reader(csvfile, delimiter=',')
        alldata={}
        for row in NCI_data:
            try:
                name_str=row[0]
                if ':' in name_str:
                    splt=name_str.split(':')
                    n_name=splt[1]
                else:
                    n_name = name_str
                alldata[n_name]=row
            except IndexError: 
                print "bad row:"+str(row)
    

    【讨论】:

    • 所以,谢谢我犯了一个愚蠢的错误,并在你们的帮助下意识到第一行是列标题,因此没有“:”格式。我认为因为它已经在 R 中工作一切正常,但忘记了在 R 中您可以在加载时指定列标题,因此它们不会被视为变量。