鱼C论坛

 找回密码
 立即注册
查看: 3109|回复: 8

[已解决]求助报错:IndexError: list index out of range

[复制链接]
发表于 2019-4-14 23:37:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
各位好,我在学习中又遇到了小问题:

先放代码:
  1. f=open('Test.log')
  2. while True:
  3.     line=f.readline()
  4.     line1=line.strip('\n')
  5.     z=line1.split(',')
  6.     s=z[3].split('=')
  7.     if line1!="":
  8.         if s[1]=='10':
  9.             print(z)
复制代码
Test.log中的内容如下:
Symbol=HMST.NQ,Type=0,Price=28.22700,Size=10
Symbol=ALBO.NQ,Type=0,Price=34.89000,Size=10
Symbol=AAON.NQ,Type=0,Price=45.65000,Size=10
Symbol=RUSHA.NQ,Type=0,Price=43.78000,Size=100
Symbol=POWI.NQ,Type=0,Price=74.41000,Size=14
Symbol=LQDA.NQ,Type=0,Price=11.30000,Size=10
Symbol=DGICA.NQ,Type=0,Price=13.26000,Size=1
Symbol=SHEN.NQ,Type=0,Price=43.73000,Size=10
Symbol=BOCH.NQ,Type=0,Price=10.93000,Size=8
Symbol=SHEN.NQ,Type=0,Price=43.19000,Size=10
Symbol=ATRC.NQ,Type=0,Price=28.09000,Size=10
Symbol=PCB.NQ,Type=0,Price=18.16000,Size=4
Symbol=KVHI.NQ,Type=0,Price=10.42000,Size=10

程序目的:
把test中的log读出来,然后只打出size=10的条目。现在的代码能够实现这个功能,但是会报错,报错内容如下:
Traceback (most recent call last):
  File "C:\Users\WENrui\Desktop\Python\hello2.py", line 6, in <module>
    s=z[3].split('=')
IndexError: list index out of range



我去查了报错原因,说是循环结束后文本存在空值,导致list index索引不到,这个空值可能是readline读取后每行末尾的换行符'\n'引起的,所以我在readline以后用了strip去掉换行符,但是依然会报错,请问这个错误应该怎么修正?

我试过在if判断语句之前print(z),不会报错,所以我觉得错误很可能出现在if判断语句这部分,能麻烦帮忙看看是哪里出错了吗?
  1. if line1!="":
  2.         if s[1]=='10':
  3.             print(z)
复制代码



最佳答案
2019-4-14 23:59:28
本帖最后由 cwhsmile 于 2019-4-15 00:01 编辑

问题不在判断条件,
错误信息的第三行指出了错误的原因,但这是治标不治本的原因,(错误提示的是:超出索引范围)。
你需要一层一层的往上推倒。

本质原因是你循环设置的不对,当f.readline()把所有的行都读取完以后并没有停止退出循环,
所以f.readline()还在不停的执行,由于文件已经没有内容了,所以f,readline()读取到的就是'\n'或者''
然后就导致s=z[3].split('=')出错,因为z已经变成了空列表,没有编号为3的元素。

解决办法有一个,用f.readlines()把文件按照行读取返回列表,用for循环迭代。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-4-14 23:53:39 | 显示全部楼层
  1. with open('Test.log') as f:
  2.     for line in f:
  3.         line = line . strip()
  4.         z = line . split(',')
  5.         s = z[3] . split('=')
  6.         if s[1] == '10':
  7.             print z
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-4-14 23:59:28 | 显示全部楼层    本楼为最佳答案   
本帖最后由 cwhsmile 于 2019-4-15 00:01 编辑

问题不在判断条件,
错误信息的第三行指出了错误的原因,但这是治标不治本的原因,(错误提示的是:超出索引范围)。
你需要一层一层的往上推倒。

本质原因是你循环设置的不对,当f.readline()把所有的行都读取完以后并没有停止退出循环,
所以f.readline()还在不停的执行,由于文件已经没有内容了,所以f,readline()读取到的就是'\n'或者''
然后就导致s=z[3].split('=')出错,因为z已经变成了空列表,没有编号为3的元素。

解决办法有一个,用f.readlines()把文件按照行读取返回列表,用for循环迭代。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-4-15 11:02:41 | 显示全部楼层

感谢回复,代码可以运行,不过还有个问题想要请教一下:为什么打开文件后就可以直接使用for循环,不需要要先按行读取文本内容吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-4-15 11:31:29 | 显示全部楼层

本帖最后由 jackz007 于 2019-4-15 11:34 编辑
wrpython 发表于 2019-4-15 11:02
感谢回复,代码可以运行,不过还有个问题想要请教一下:为什么打开文件后就可以直接使用for循环,不需要 ...


       因为 Python 文件对象使用 readlin() 方法循环读取文件无法确定是否到达 EOF(文件结束)点,因而无法确定应该在什么时机结束循环。而采用 for line in f: 这种方式可以一次性读取并把文件中所有的文本行以列表的形式呈现出来,从而,可以通过变量 line 来枚举、遍历到每一行文本内容。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-4-15 11:42:54 | 显示全部楼层
cwhsmile 发表于 2019-4-14 23:59
问题不在判断条件,
错误信息的第三行指出了错误的原因,但这是治标不治本的原因,(错误提示的是:超出索 ...

谢谢指导,我尝试重写了代码如下:
  1. f=open('Test.log')
  2. for line in f.readlines():
  3.     line1 = line.strip()
  4.     a=line1.split(',')
  5.     s=a[3].strip().split('=')
  6.     if s[1] == '10':
  7.         print(a)
  8.    
复制代码
这样就可以输出了,输出的结果如下:
['Symbol=HMST.NQ', 'Type=0', 'Price=28.22700', 'Size=10']
['Symbol=ALBO.NQ', 'Type=0', 'Price=34.89000', 'Size=10']
['Symbol=AAON.NQ', 'Type=0', 'Price=45.65000', 'Size=10']
['Symbol=LQDA.NQ', 'Type=0', 'Price=11.30000', 'Size=10']
['Symbol=SHEN.NQ', 'Type=0', 'Price=43.73000', 'Size=10']
['Symbol=SHEN.NQ', 'Type=0', 'Price=43.19000', 'Size=10']
['Symbol=ATRC.NQ', 'Type=0', 'Price=28.09000', 'Size=10']
['Symbol=KVHI.NQ', 'Type=0', 'Price=10.42000', 'Size=10']

不过现在输出的还只是列表中的元素,和原来的文本内容有点不一样,因为line1.split()返回的a还是列表,所以直接输出a还是输出的列表,请问如何才能直接把列表全部以文本方式输出呢?
我自己鼓捣出来的方法是按元素逐个输出

  1. f=open('Test.log')
  2. for line in f.readlines():
  3.     line1 = line.strip()
  4.     a=line1.split(',')
  5.     s=a[3].strip().split('=')
  6.     if s[1] == '10':
  7.         print(a[0],a[1],a[2],a[3])
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-4-15 12:13:18 | 显示全部楼层
wrpython 发表于 2019-4-15 11:42
谢谢指导,我尝试重写了代码如下:
这样就可以输出了,输出的结果如下:
['Symbol=HMST.NQ', 'Type=0', ...

字符串有个.join方法,
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-4-15 12:56:29 | 显示全部楼层
cwhsmile 发表于 2019-4-15 12:13
字符串有个.join方法,

谢谢!中午想了想,后续要做处理的话其实还是列表的形式更方便 ;-)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-4-15 15:25:20 From FishC Mobile | 显示全部楼层
用readline() 最后加个判断条件就行
if f.readline()==""
    break
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-9 19:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表