索引超出python程序的范围



我写了一个程序,即使字母重复出现也应该能识别单词,例如"JJJOOOHHHNNN"应该被识别为"JOHN",但是当我运行它时,我得到一个错误,索引超出了范围,不知道为什么会发生。注:我知道有一种更简单的方法来做到这一点,但我想使用re.match()和pop()函数。

import re 
letters="ABCDEFGHIJKLMNOPRSTQUWXYZ"
def recognize_name(name):
name=name.upper()
result=[]
temp=len(name)
while len(name)!=0:
for j in letters:
if re.match("^{0}+".format(j), name):
name=list(name)
while name[0] == j:
name.pop(0)
name="".join(name)
else:
continue
result+=j
result="".join(result)
return result
print(recognize_name("JJJOOOHHHNNN"))
Exception has occurred: IndexError
list index out of range
File "C:UsersmacieOneDriveDesktopFolderMy_repoplik2.py", 
line 11, in recognize_name
while name[0] == j:
File "C:UsersmacieOneDriveDesktopFolderMy_repoplik2.py", 
line 19, in <module>
print(recognize_name("JJJOOOHHHNNN"))

运行时错误

错误的发生是因为name最终将减少到0长度,此时对name[0]的检查将无法进行。这可以通过添加len(name) > 0检查来修复。

while len(name) > 0 and name[0] == letter:

注意,为了保护name[0],and必须这样转。

程序也会在result += j行出错。+=用于将列表连接在一起;要向列表中添加单个元素,调用result.append(j)。这一行也应该再缩进一级。

逻辑错误Vletters中省略。要获得一串大写字母,而不必手动输入,以免出现这种错误,您可以执行

from string import ascii_uppercase as letters

最终代码:

import re
from string import ascii_uppercase as letters
def recognize_name(name):
name=name.upper()
result=[]
temp=len(name)
while len(name)!=0:
for j in letters:
if re.match("^{0}+".format(j), name):
name=list(name)
while len(name) > 0 and name[0] == j:
name.pop(0)
name="".join(name)
else:
continue
result.append(j)
result="".join(result)
return result
print(recognize_name("JJJOOOHHHNNN"))

实际上有两个问题。一个与索引错误有关,另一个是结果的实际构造(追加)。

while name[0] == j:
name.pop(0)

这将删除所有匹配字母的出现,直到它被完全删除。基本逻辑没有问题,直到最后一个字母被弹出,然后name变成一个空字符串。

# 1)
while name[0] == j:  # name = list('JJJOOOHHHNNN') , j: 'J'
name.pop(0)  # name = 'JJOOOHHHNNN'
# 2)
while name[0] == j:  # name = list('JJOOOHHHNNN') , j: 'J'
name.pop(0)  # name = 'JOOOHHHNNN'
# 3)
while name[0] == j:  # name = list('JOOOHHHNNN') , j: 'J'
name.pop(0)  # name = 'OOOHHHNNN'
# 4) 
#  name[0] does not equal j anymore, so continue and append j to the result, 
#  so repeating consecutive letters get "collapsed" to 1
....
# Eventually, your name string will become 'NNN' > 'NN' > 'N'
# (I know it's actually a list at this point in the code)
while name[0] == j:  # name = ['N'] , j: 'J'
name.pop(0)  # name = []
# Now name list it is empty! so
name[0]  # raises IndexError

因此在while循环中添加一个条件,以确保列表中存在内容

while name and name[0] == j:

第二个问题,result += j缩进不足。它必须在for循环

for j in letters:
. . . 
result += j

相关内容

最新更新