Python 人工限制时索引超出范围

Python 人工限制时索引超出范围,python,list,Python,List,当我运行这个程序时,有时会收到一个错误。但是,这个错误是不可能的,因为我使用的是8x8网格,我限制输入,使它们只能是0-7之间的数字,以遵守列表索引从0开始的事实 用户必须输入坐标(1-8),(A-H),程序将通过系统地浏览公司列表并反复将这些坐标与用户给出的坐标进行比较来检查这些坐标是否正确。如果跳线匹配,则会出现一条消息,坐标上的“Z”将变为“X”,表示命中。如果猜测不匹配,则这些坐标上的“Z”将变为“M”,表示未命中 CompShips=[[1,0],[1,1],[2,2],[2,3],[

当我运行这个程序时,有时会收到一个错误。但是,这个错误是不可能的,因为我使用的是8x8网格,我限制输入,使它们只能是0-7之间的数字,以遵守列表索引从0开始的事实

用户必须输入坐标(1-8),(A-H),程序将通过系统地浏览公司列表并反复将这些坐标与用户给出的坐标进行比较来检查这些坐标是否正确。如果跳线匹配,则会出现一条消息,坐标上的“Z”将变为“X”,表示命中。如果猜测不匹配,则这些坐标上的“Z”将变为“M”,表示未命中

CompShips=[[1,0],[1,1],[2,2],[2,3],[2,4],[3,0],[3,1],[3,2],[5,4],[5,5],[5,6],[5,7],[1,7],[2,7],[3,7],[4,7],[5,7]] 
FRow1=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow2=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow3=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow4=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow5=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow6=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow7=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow8=["Z","Z","Z","Z","Z","Z","Z","Z",]
def PrintFireBoard():
    print(Index)
    print(FRow1)
    print(FRow2)
    print(FRow3)
    print(FRow4)
    print(FRow5)
    print(FRow6)
    print(FRow7)
    print(FRow8)
FireBoard=[FRow1,FRow2,FRow3,FRow4,FRow5,FRow6,FRow7,FRow8]
while len(CompShips) !=0 or CompSuccess==17:
    FireRow=input("Please Choose The Row That You Wish To Fire Upon (1-8) ")
    FireIndex=input("Please Choose The Column That You Wish To Fire Upon (A-H) ")
    #As Lists start at 0
    FireRow=int(FireRow)-1
    if FireIndex==("A"):
        FireIndex=0
    elif FireIndex==("B"):
        FireIndex=1
    elif FireIndex==("C"):
        FireIndex=2
    elif FireIndex==("D"):
         FireIndex=3
    elif FireIndex==("E"):
        FireIndex=4
    elif FireIndex==("F"):
        FireIndex=5
    elif FireIndex==("G"):
        FireIndex=6
    elif FireIndex==("H"):
        FireIndex=7
Guess=[FireRow,FireIndex]
#Check To See If Correct
UserSuccess=0
for i in CompShips:
    if Guess==i:
        CompShips.remove(Guess)
        UserSuccess=1
    else:
        pass
if UserSuccess==1:
    print("HIT")
    print(FireRow)
    print(FireIndex)
    FireBoard[[FireRow][FireIndex]]=("H")
    PrintFireBoard()
else:
    print("MISS")
    print(FireRow)
    print(FireIndex)
    FireBoard[[FireRow][FireIndex]]=("M")
    PrintFireBoard()
我收到错误消息:

IndexError: string index out of range

看起来像这两条线

FireBoard[[FireRow][FireIndex]]=("H")
FireBoard[[FireRow][FireIndex]]=("M")
应该是

FireBoard[FireRow][FireIndex]="H"
FireBoard[FireRow][FireIndex]="M"

解释:在您的旧代码中,
FireBoard[[FireRow][FireIndex]=(“H”)

[FireRow][FireIndex]
意味着,给定一个列表
[FireRow]
(仅包含一个元素),获取
FireIndex
-th元素。这不是你想做的

例如
[3][0]
返回
3
,而
[3][1]
给出
索引器

看看


还要注意的是
(“H”)
与字符串
“H”
相同。没有必要添加括号。

您问题中的缩进已关闭。我认为所有的代码都来自

 Guess=[FireRow,FireIndex]
直到结束时,前面应加4个空格

由于未定义打印(索引),我已将其删除

要访问防火板,请使用:

FireBoard[FireRow][FireIndex]
而不是

FireBoard[[FireRow][FireIndex]]
这应该是有效的

CompShips=[[1,0],[1,1],[2,2],[2,3],[2,4],[3,0],[3,1],[3,2],[5,4],

[5,5],[5,6],[5,7],[1,7],[2,7],[3,7],[4,7],[5,7]] 
FRow1=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow2=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow3=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow4=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow5=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow6=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow7=["Z","Z","Z","Z","Z","Z","Z","Z",]
FRow8=["Z","Z","Z","Z","Z","Z","Z","Z",]
def PrintFireBoard():
    print(FRow1)
    print(FRow2)
    print(FRow3)
    print(FRow4)
    print(FRow5)
    print(FRow6)
    print(FRow7)
    print(FRow8)
FireBoard=[FRow1,FRow2,FRow3,FRow4,FRow5,FRow6,FRow7,FRow8]
while len(CompShips) !=0 or CompSuccess==17:
    FireRow=input("Please Choose The Row That You Wish To Fire Upon (1-8) ")
    FireIndex=input("Please Choose The Column That You Wish To Fire Upon (A-H) ")
    #As Lists start at 0
    FireRow=int(FireRow)-1
    if FireIndex==("A"):
        FireIndex=0
    elif FireIndex==("B"):
        FireIndex=1
    elif FireIndex==("C"):
        FireIndex=2
    elif FireIndex==("D"):
         FireIndex=3
    elif FireIndex==("E"):
        FireIndex=4
    elif FireIndex==("F"):
        FireIndex=5
    elif FireIndex==("G"):
        FireIndex=6
    elif FireIndex==("H"):
        FireIndex=7
    Guess=[FireRow,FireIndex]
    #Check To See If Correct
    UserSuccess=0
    for i in CompShips:
        if Guess==i:
            CompShips.remove(Guess)
            UserSuccess=1
        else:
            pass
    if UserSuccess==1:
        print("HIT")
        print(FireRow)
        print(FireIndex)
        FireBoard[FireRow][FireIndex]=("H")
        PrintFireBoard()
    else:
        print("MISS")
        print(FireRow)
        print(FireIndex)
        FireBoard[FireRow][FireIndex]=("M")
        PrintFireBoard()

这里有一个更干净的代码

CompShips=[[1,0],[1,1],[2,2],[2,3],
           [2,4],[3,0],[3,1],[3,2],
           [5,4],[5,5],[5,6],[5,7],
           [1,7],[2,7],[3,7],[4,7],
           [5,7]] 

FRow=[["Z"]*8]*8   #1 More Pythonic


def PrintFireBoard():
    #print(Index)
    for i in range(0,8):
        print(FRow[i])

FireBoard=FRow[:]  #NOTE THIS ONE!!!

mydict = {}
for i,key in enumerate(["A","B","C","D","E","F","G","H"]): #2 More Pythonic
    mydict[key] = i


while len(CompShips) !=0 or CompSuccess==17:
    FireRow=input("Please Choose The Row That You Wish To Fire Upon (1-8) ")
    FireIndex=input("Please Choose The Column That You Wish To Fire Upon (A-H) ")

    FireRow=int(FireRow)-1
    FireIndex = mydict[FireIndex]
    Guess=[FireRow,FireIndex]
    print(Guess)

    UserSuccess=0
    for i in CompShips:
        if Guess==i:
            CompShips.remove(Guess)
            UserSuccess=1
        else:
            pass
    if UserSuccess==1:
        print("HIT")
        print(FireRow,FireIndex)
        FireBoard[FireRow][FireIndex]="H" #3 your problem here
        PrintFireBoard()
    else:
        print("MISS")
        print(FireRow,FireIndex)
        FireBoard[FireRow][FireIndex]="M"
        PrintFireBoard()
1) 正如在评论中所解释的,这只是创建列表的更好方法!。记住干燥的原则!不要重复你自己

2) 而不是使用所有if-else将“A”转换为0。您可以使用字典查找代替

3) 你的问题似乎就在这里!将此项更正为
FireBoard[FireRow][FireIndex]=“H”


注:注意这个!!!:我不只是把防火板作为FRow的别名!我正在把它作为一个新的列表复制到防火板上!这里有一本关于它的书。我这样做是为了防止你不想修改你原来的FRow列表

它能告诉你索引器是在哪一行发生的吗?只是一个小小的注释,而不是像那样构建板,你可以使用这个巧妙的技巧将项目扩展到一个列表中
[“Z”]*8
将生成
['Z'、'Z'、'Z'、'Z'、'Z'、'Z']
因此
[[Z”]*8]*8
将生成一个以“Z”为元素的8x8列表。@AxelPersinger将创建外部数组的8个副本,因此,如果修改其中一个,它们都将被更改。你需要这样做:
['Z'代表范围内的i(8)]代表范围内的j(8)]
@user3080953,没错,我完全忘记了!您的答案是正确的。@AxelPersinger:
[“Z”]*8
可以,因为字符串是不可变的,对它们的任何操作实际上都会替换对象;但是
[[“Z”]*8]*8
是一个很大的“否”-您将得到一个包含对同一子列表的8个引用的列表,因此如果您这样做-说
FireBoard[0][0]=“a”
您将在每行的第一列中得到一个
a
,因为所有行都引用相同的列表。正确的方法是
[[“Z”]*8表示范围(8)]