【问题标题】:Python Itemgetter 'string index out of range'Python Itemgetter'字符串索引超出范围'
【发布时间】:2015-04-21 09:59:12
【问题描述】:

下面的代码是我用来排序和打印 csv 文件的代码。有 8 列,我想按第 7 列进行排序,这是一个整数。我有这个错误:

Traceback (most recent call last):
  File "Task 3.py", line 271, in <module>
    sort = sorted(file, key=operator.itemgetter(6), reverse=False)
  IndexError: string index out of range

这是我为此使用的代码块:

file = open("class1.csv", "r")
sort = sorted(file, key=operator.itemgetter(7), reverse=False)
for eachline in sort:
    print (eachline.replace("\n", ""))
file.close()

任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: python csv indexing range


    【解决方案1】:

    您得到的字符串索引错误是因为使用 key=operator.itemgetter(7)sorted() 会导致它尝试根据第 8th 字符而不是每行数据的该列进行排序csv 文件。

    您可以通过首先用 , 字段分隔符分隔每一行来解决这个问题:

    row.split(',')
    

    为了简化将这两个操作一个接一个地应用于每一行,可以将它们与lambda 组合成一个复合函数。在下面的代码中,您的代码中使用的 operator.itemgetter(7) 已被替换为对新的自定义 itemgetter-like 函数的调用:

    def csv_itemgetter(index, delimiter=','):
        composite = lambda row: row.split(delimiter)[index]
        return composite
    
    with open("class1.csv") as file:
        for eachline in sorted(file, key=csv_itemgetter(7)):
            print eachline,
    

    如果文件中的某些行可能少于 8 列,您可以轻松地将错误处理添加到处理它们的自定义 itemgetter

    def csv_itemgetter(index, delimiter=',', default=''):
        def composite(row):
            try:
                return row.split(delimiter)[index]
            except IndexError:
                return default
        return composite
    

    【讨论】:

      【解决方案2】:

      您的代码不起作用,因为operator.itemgetter(7) 正在访问该行的第 8 个字符,而不是第 8 个

      您需要先将 csv 解析成列:

      import csv
      
      with open("class1.csv") as f:
          # since you sort the data, we may as well read everything at once
          data = list(csv.reader(f))  
      
      sort = sorted(data, key=operator.itemgetter(7), reverse=False)
      for eachline in sort:
          print(eachline.replace("\n", ""))
      

      但是,如果您的某些行少于 8 列,这可能仍然不起作用。您可以通过以下方式解决此问题:

      with open("class1.csv") as f:
          # ensure at least 8 columns, by appending emptystrings
          data = [
              row + [''] * (8 - len(row))
              for row in csv.reader(f))
          ]
      

      【讨论】:

        猜你喜欢
        • 2016-02-10
        • 2019-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-13
        • 1970-01-01
        • 2016-08-11
        相关资源
        最近更新 更多