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个数字存储在不同的行中拜托,如果有任何方法可以帮助你,请告诉我 感谢
答案 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.txt
到range
,我确实解决了显然是另一个错误(您永远不会处理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