列表索引超出范围,循环不迭代

时间:2013-08-02 13:30:59

标签: python

如果我通过向您展示我试图操作的.csv文件来解释可能会更容易:

https://www.dropbox.com/s/4kms4hm28y7sv8w/Test1.csv

我有数百行这样的数据,但我们已经决定我们想要它采用不同的格式,每个化石属和物种(W,X,Y列)都有自己的行。

我的Python知识非常有限,但是我想尝试使用它,无论是分割这些单元格还是将每个值插入到下面的行中,从中分割出来。我打算手动将它们拖到正确的列并在Excel上向下拖动其他详细信息。

代码:

#nektonic=[row[22].split(',') for row in data]
#infaunal=[row[23].split(',') for row in data]  
#epifaunal=[row[24].split(',') for row in data] 

f=0
r=0

def splitfossils(f, r): 
    #f=0 #fossil index: counter that moves the selection along the fossils in a cell that are being split by commas
    for row in data:
        r=(data.index(row)+1) #row index: counter so that split fossils can be inserted beneath the row that is being processed; the +1 is to ensure that the counter starts on 1, not 0.
        if row[22] == '':
            continue #if no fossils are found, move onto the next row
        else:
            nektonic=[row[22].split(',')] #nektonic fossils are found to be in the 23rd column of the spreadsheet
            if len(nektonic) == 1:
                data.insert(r,(nektonic[f])) #if only one fossil is present in the nektonic list, insert only that fossil and do not increase counter number 
            else:
                while f < len(nektonic): #the while loop will loop until the split fossils have been processed
                    data.insert(r,(nektonic[f])) #each split fossil will be inserted into a row below                                   
                    f=f+1 #the fossil index moves on to the next fossil
                    r=r+1 #the next fossil will be inserted into the row below the previous fossil
                    return f
                    return r


splitfossils(f, r)

当前错误消息是列表索引超出范围(突出显示第19行和第34行)。

我尝试通过函数传递各种变量,看看是否有所不同,但我先前的错误是“for”循环不会迭代。 “数据”列表的长度是29,但是我打印出nektonic [f]的唯一打印件是“Stomohamites Simplex”,这是电子表格中1W的唯一值。

我不确定循环中的所有循环是否都能正常工作,就像我说我的知识非常基础一样。任何人都可以告诉我代码有什么问题,以及解决这个问题的方法可能更简单吗?

由于

编辑:我完成后改变了我对此所做的方法。它现在有效,非常感谢你的帮助。

import csv

out=open("Test1.csv", "rb")
data=csv.reader(out)
data=[row for row in data]
out.close() 

nektonic=[]

def splitfossils(): 
    for row in data:        
        nektonic=row[22].split(',')
        if len(nektonic)>1:
            for fossil in nektonic:
                newrow=[0 for i in range(22)]
                newrow.append(fossil)
                output.writerow(newrow)

        else:
            output.writerow(row)
    return data

out=open("new_test2.csv", "wb")
output=csv.writer(out)
splitfossils()

2 个答案:

答案 0 :(得分:4)

在Python中,身份很重要。因此,代码

while f < len(nektonic): #the while loop will loop until the split fossils have been processed
    data.insert(r,(nektonic[f])) #each split fossil will be inserted into a row below                                   
    f=f+1 #the fossil index moves on to the next fossil
    r=r+1 #the next fossil will be inserted into the row below the previous fossil
    return f
    return r

在单次迭代后返回,因为return f会立即被击中。你可能想要进一步缩进(实际上都是returns)。

话虽如此,在Python中你不需要使用索引来迭代数组,你只需这样做:

for fossil in nektonic:
    data.insert(r, fossil)

迭代行的外部循环相同。

答案 1 :(得分:0)

问题是您正在尝试修改正在迭代的列表。我认为这不是Python的好方法。尝试将数据复制到新列表(由于引用了对象而不是复制对象,因此它具有内存效率)。像这样:

import csv

out=open("Test1.csv", "rb")
data=csv.reader(out)
data=[row for row in data]
out.close()    

#nektonic=[row[22].split(',') for row in data]
#infaunal=[row[23].split(',') for row in data] 
#epifaunal=[row[24].split(',') for row in data]

def splitfossils():
    result = []
    for row in data:
        if row[22] == '':
            continue #if no fossils are found, move onto the next row
        else:
            nektonic=[row[22].split(',')]
            result.append(row)
            result.append(nektonic)
    return result


print splitfossils()

我不确定上述代码是否是您问题的直接答案,但请以这种方式尝试...