收到列表索引超出范围错误

时间:2010-08-15 23:47:47

标签: python debugging list

嘿伙计们,初学者在这里。我编写了一个程序,将文件输出到.txt,并使用另一个程序读取它们并使用它们。我使用了一个列表来存储这些值(len(..)给我100个所有文件)。但是,每当我运行这个:

for w in range(1,20): # i want files file01-file20 excluding file00
    for x in range(100):
        c=c+1 #counter to keep list position on f=0
        exec "f=open('file%02d.txt','r').readlines()"%w #stores data from file00,file01,file02...
        f00=open('file00.txt','r').readlines() #same as ^ but from file00
        for y in range(100):
            xvp=float(f[c].rstrip('\n')) #the error is on this line; the file are stored in vertical order
            pvp=float(f00[y].rstrip('\n')) #maybe even this one
            #and i do stuff with those values...

我排队第12行,     XVP =浮子(F并[c] .rstrip( '\ n'))     IndexError:列表索引超出范围

注意:.txt的

中有100个数字存储在不同的行中

拜托,如果有任何方法可以帮助你,请告诉我 感谢

3 个答案:

答案 0 :(得分:4)

你似乎正在增加c两千次(20次100次 - 实际上只有1900次,因为range(1,20) 达到值20,因为你似乎在评论中渴望 - 当然,如果你使用它来索引100的列表,你就会超出范围!整个代码相当混乱,我建议彻底重构它,以避免exec并以Python的方式做事。假设Python 2.6或更高版本(在2.5中,模块开头需要from __future__ import with_statement):

f00 = open('file00.txt').readlines()
for w in range(1, 21):
    for x in range(100):
        with open('file%02d.txt' % w) as f:
            for line in f:
                xvp = float(line)
                for line00 in f00:
                    rvp = float(line00)
                    do_stuff(xvp, rvp)

我不知道这是否是您想要的逻辑 - 将file00.txt的每一行与来自其他20个文件的每个行的耦合 - 但至少这使它成为< em> clear 哪些行与哪个行耦合;-)。如果您想要的只是将file00.txt第一行行与其他每一行的第一行相连,那么第二行与第二行等,然后添加import itertools在模块的开头,将with的内容更改为:

            for line00, line in itertools.izip(f00, f):
                rvp = float(line00)
                xvp = float(line)
                do_stuff(xvp, rvp)

等等。

请注意,我一劳永逸地读取内存中的所有file00.txt(进入f00行列表),因为显然您需要多次循环这些内容,但这不是其他文件需要。

一个明显的优化是只将file00.txt的行转换为浮点数一次,用

替换f00 =语句
with open('file00.txt') as f:
  rvps = [float(line) for line in f]

然后直接使用rvps,而不是每次都在f00的字符串上重复转换 - 例如,在第二个版本(使用itertools.izip的那个)中:

            for rvp, line in itertools.izip(rvps, f):
                xvp = float(line)
                do_stuff(xvp, rvp)

编辑:我看到我做了很多微小的改进,但很难意识到我这样做了,也许我最好解释一下;-)。打开文件进行阅读时无需传递'r'(不能伤害,但省略它是非常惯用的)。在调用float之前,不需要从字符串中去掉尾随(或者为此引导)空格 - float愉快地跳过所有这样的前导和尾随空格本身。通过修改适用的file20.txtrange,我确实解决了显然是另一个错误(您永远不会处理range(1, 21))。

with open(...) as f:语句对打开的文件对象执行打开,绑定名称f,并且一旦它们控制的语句块完成,就保证文件正确关闭 - 它应该几乎总是优先于独立的open使用,因为确保所有文件都是关闭的ASAP是非常好的做法(with语句有许多其他优秀的用例,但这是最常见的一个,也是这个功能所必需的唯一一个。)

直接在打开的文件对象f上循环(如果文件以文本模式打开,默认情况下并在此处应用),for line in f:一个接一个地提供{ {1}}(不需要一次将它们全部保存在记忆中)并且是一种非常受欢迎且非常好的Pythonic习语。

我在推荐的优化中使用的构造f被称为“列表理解”,它是构建新列表的循环的一种非常快速和紧凑的替代方法。

rvps = [float(line) for line in f],给定了一些迭代,提供了一个迭代,其项目是由其他迭代项“走进锁步”的元素组成的元组。内置的itertools.izip是类似的,但是(在Python 2中)它在内存中构建了一个列表,zip避免了,所以学习使用itertools.izip版本来避免浪费记忆(对于像你这样的小文件来说并不是很重要,但是好习惯最好学习并且“只是应用”而不是每次都要反思它们 - 只有一个人不会每天早上开始思考是否一个应该刷一个人的牙齿,但只是去做,这是一个良好的习惯; - )。

我确信还有更多,但这就是想到的东西 - 随时可以问我是否可以提供进一步的帮助!

答案 1 :(得分:1)

  

存储了100个号码   .txt中的单独行

但在

for w in range(1,20): # i want files file01-file20 excluding file00
    for x in range(100):
        c=c+1 #counter to keep list position on f=0

你将c递增20 * 100 = 2000次。

也许你需要在“w”循环中使用c = 0或者只使用x代替c?

答案 2 :(得分:1)

根据您描述文件的方式,您正在错误地索引它们。通过使用c,它为第二个循环的每次迭代递增。它将达到最高2000的值。使用x似乎是合乎逻辑的选择。

#restructured for efficiency
file = open('file00.txt','r')
f00 = file.readlines() #no need to reopen the file for every iteration
file.close() #always close the file when done with
for w in range(1,20):
    file = open('file%02d.txt'%w,'r')
    f = file.readlines() #only open once per iteration
    file.close()
    for x in range(100):
        xvp = float(f[x].rstrip('\n'))
        for y in range(100):
            pvp = float(f00[y].rstrip('\n'))
            #do stuff