索引错误:字符串索引超出范围。

3
我正在遇到一个问题。
Traceback (most recent call last):   File "H:\Documents\game.py", line 73, in <module>
    if attemptThis[i] != target[i]: IndexError: string index out of range Press any key to continue . . .

运行这段代码时出现错误。

#-----------------------------------------------------
# Python 'Evolution of Text' Program
# More programs at: usingpython.com/programs
#-----------------------------------------------------

possibleCharacters = string.ascii_uppercase + ' .!?;:='

target = """
       lMMMMMMMM                                                             .MMMM=         MMM                               MMM     
       lMM     MMl                                                          M=M   MMM       =MM                               MMM           
       lMM     M=.  MMM  M=M=   M=MM=MM    =M=====     M=MMMM=              M=M          MM=MMM==l  ==M===M=    MMM MMMM   =M=MM==MM   
       lMM     M=.  MMM==     MMM    .==  ==M....    =l=                      l===l=M.      MMM          .MMM   MMM=          MMM    
       lMM======    MMM       MM========   ......=ll   .....MMl             lll    =MM      =MM    l==....M=M   =MM           MMM 
       lM=          M=M         M=====M   =====M=M   =======MM               .M===MMM       MMM     =M====MMM   MMM           MMM      
"""
attemptThis = ''.join(random.choice(possibleCharacters) for i in range(len(target)))
attemptNext = ''

completed = False

generation = 0

while completed == False:
    print(attemptThis)
    attemptNext = ''
    completed = True
    for i in range(len(target)):
        if attemptThis[i] != target[i]:
            completed = False
            attemptNext += random.choice(possibleCharacters)
        else:
            attemptNext += target[i]
    if generation == 1000:
        break
    generation += 1
    attemptThis = attemptNext

我在这里找到了这段代码(链接),并根据自己的需求进行了修改。在添加退出条件之前,它是可以正常工作的。

if generation == 1000:
    break

我把它添加进去是因为生成ASCII所需的时间太长了。我正在一个小项目中使用这个作为标题屏幕,所以将其修复并不是非常关键,我可以随时返回到使用Print """Text Here"""命令。


1
如果,比如说,len(target) 是6,那么 range(len(target)) 将会给出0,1,2,3,4,5。更有可能的是 attemptNexttarget 短。 - cdarke
你说得对。我错过了最后一行 attemptThis = attemptNext - Håken Lid
1
当我尝试运行你的代码时,从 attemptThis 打印出来的内容是垃圾信息,但我并没有看到你所描述的错误。在 OS X 上通过 2.7.10 和 3.5.1 版本测试过。 - cdarke
你能解释一下你的代码的原因吗?它应该做什么?你的 while 循环有哪些中断情况? - TheLazyScripter
无法复现,除非我弄错了,attemptThis应该在while循环的每次迭代中构建为与target相同的大小,因此我不明白它们如何长度不同。 - Tadhg McDonald-Jensen
1个回答

2

直接循环遍历集合比使用索引更符合Python风格。由于我对您的程序应该做什么感到好奇,我还重新编写了其他部分以使其运行。

import time, random, string
target = """  
    lMMMMMMMM                                                
    lMM     MMl                                              
    lMM     M=.  MMM  M=M=   M=MM=MM    =M=====     M=MMMM=  
    lMM     M=.  MMM==     MMM    .==  ==M....    =l=        
    lMM======    MMM       MM========   ......=ll   .....MMl 
    lM=          M=M         M=====M   =====M=M   =======MM  

     .MMMM=         MMM                               MMM    
    M=M   MMM       =MM                               MMM    
    M=M          MM=MMM==l  ==M===M=    MMM MMMM   =M=MM==MM 
      l===l=M.      MMM          .MMM   MMM=          MMM    
    lll    =MM      =MM    l==....M=M   =MM           MMM    
     .M===MMM       MMM     =M====MMM   MMM           MMM    
"""

chars = list(set(target + string.ascii_uppercase) - {'\n'})
attempt = ''.join('\n' for c in target)  
# First attempt is just a bunch of newlines. This makes the 
# text alignment correct after the first run through the loop

while target != attempt:
    attempt = ''.join(
        tc if tc == ac else random.choice(chars)
        for tc, ac in zip(target, attempt)
    )
    clearscreen = '\033c'  # linux terminal control character
    print(clearscreen + attempt)
    time.sleep(0.05)

这是一个预览,展示了它的外观(链接指向asciinema.org)。 asciicast

那似乎做我想要的事情,但是我需要在回到课堂后进行测试。 - user6436663

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接