Python:列表超出范围

2024-10-01 07:49:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试构建一个基本的编码器和解码器来学习一些Python。这就是我目前的代码:

import time

def mainSub():
    sString = input('Please enter a string:')
    sChoose = input('Would you like to [e]ncrypt or [d]ecrypt?:')
    encrypts = ["a","362","b","637","c","391","d","678","e","912","f","718","g","461","h","888","i","123","j","817","k","571","l","111","m","036","n","182","o","951","p","711","q","500","r","125","s","816","t","183","u","619","v","678","w","911","x","719","y","567","z","678"," ","-"]
    if sChoose == "e":
        for x in range(0, len(encrypts)):
            sOutput = sString
            sOutput = sOutput.replace(encrypts[x], encrypts[x+1])
    elif sChoose == "d":
        for x in range(0, len(encrypts)):
            sOutput = sString
            sOutput = sOutput.replace(encrypts[x+1], encrypts[x])
    else:
        print("You did not choose for encrypt or decrypt. Please only enter e or d.")
        print(sOutput)

while True:
    mainSub()

但是,每当控制台应替换为以下错误时,它就会中止:

Traceback (most recent call last):
  File "C:/Users/Max/Desktop/test.py", line 20, in <module>
  mainSub()   File "C:/Users/Max/Desktop/test.py", line 10, in mainSub
  sOutput = sOutput.replace(encrypts[x], encrypts[x+1])
IndexError: list index out of range

我找不到错误。有人能帮我吗?你知道吗


Tags: orinforinputlenrangereplaceprint
3条回答

你有一个循环

for x in range(0, len(encrypts)):

这意味着x将取0len(encrypts) - 1之间的值。你知道吗

例如,如果len(encrypts)4,则x将取03之间的值。你知道吗

现在,您正在尝试访问encrypts[x+1]。在最后一次迭代中(其中x将是len(encrypts) - 1),表达式

encrypts[x+1]

相当于

encrypts[len(encrypts) - 1 + 1]
encrypts[len(encrypts)]

这将产生一个Error,因为列表索引从0开始,而不是从1开始。你知道吗

那么,你能做什么?

您可以在1中减小循环范围:

for x in range(0, len(encrypts)-1):

但要注意这种变化所带来的影响。你知道吗

这里假设加密数组的长度是8。你知道吗

for x in range(0, len(encrypts)):
            sOutput = sString
            sOutput = sOutput.replace(encrypts[x], encrypts[x+1])
elif sChoose == "d":
    for x in range(0, len(encrypts)):
        sOutput = sString
        sOutput = sOutput.replace(encrypts[x+1], encrypts[x])

因此,对于索引为零的数组,当x为7时,x将在0-7的范围内迭代:- 出口=sOutput.替换(加密[7],加密[8+1]) 在上面的一行中,您试图访问加密[9]的位置,该位置超出范围。你知道吗

所以你的程序应该在0到len(加密)-1的范围内

根据其他人的回答,你是在用一个索引的东西来删除好的旧的。一个可能的解决方案是根本不做任何索引篡改:

# Let's put this line out of the for loop to prevent clearing changes every iteration
sOutput = sString 
for current_item, next_item in zip(encrypts, encrypts[1:]):
    sOutput = sOutput.replace(current_item, next_item)

zip获取两个iterable,并返回包含每个iterable的一项的元组,在最短iterable用尽时结束。通过用encrypts[1:]压缩encrypts,可以得到一系列元组,其中包含encrypts中的相邻元素。你知道吗

如果encrypts相当大,那么使用itertools模块中的izip会更高效。使用izip就像使用zip一样,它将返回一个延迟计算的生成器对象,而不是首先创建整个元组列表。你知道吗

编辑:好再次检查您的代码时,它有几个根本错误。我上面的内容复制了您的代码所做的操作而不产生索引错误,但是您的代码所做的实际上是不正确的。实际上,您需要将第一项与第二项、第三项与第四项等配对,而您当前正在将第一项与第二项、第二项与第三项、第三项与第四项等配对

下面是加密的方法:

for odd_elem, even_elem in zip(encrypts[::2], encrypts[1::2]):
    sOutput = sOutput.replace(odd_elem, even_elem)

或者像@padraic cunningham所说的,使用dict,因为你一次加密一个字符。下面是加密的方法:

encrypt_dict = dict(zip(encrypts[0::2], encrypts[1::2]))
sOutput = ''.join(encrypt_dict[char] for char in sString)

使用dicts进行解密比较困难,因为您没有将所有内容都加密为3个数字(空格转换为“-”)。它仍然是可行的,首先在'-'上拆分,然后进一步分块为3个数字,每个数字,然后通过一个解密dict运行它。或者你可以根据@padraic cunningham将空格转换成'--'。你知道吗

相关问题 更多 >