【问题标题】:Python: TypeError: 'str' object does not support item assignmentPython:TypeError:“str”对象不支持项目分配
【发布时间】:2016-10-27 04:55:11
【问题描述】:

我在制作一个简单的战舰游戏时遇到了这个问题。这是我的代码:

board = []
row = ['O'] * 5 #<<<<determine the board size here 
joined_O = '  '.join(row)


for i in range(5): #<<<<determine the board size here
    board.append(joined_O)
    print(joined_O)

from random import randint #<<<< this code is to determine where the ship is. It is placed randomly.
ship_row = randint(1,len(board))
ship_col = randint(1,len(board))

print(ship_row,', ',ship_col,'\n')

print('Shoot missile to the ship')
missile_row = int(input('row   : '))
missile_col = int(input('column: '))

#I really don't know where you're supposed to put the int() thingy so i put it everywhere
if int(missile_row) == int(ship_row) and int(missile_col) == int(ship_col):
    print("Congratulation! You've hit the ship.")
    break
elif int(missile_row) >= len(board) or int(missile_col) >= len(board):
    print('Sorry! Area is out of range.')
    break
else:
    print('Missile missed the target')
    board[int(missile_row)][int(missile_col)] = 'X'
    print(board)

我试图重新分配导弹击中“X”的位置的“O”,但随后它显示

TypeError: 'str' 对象不支持项目分配。

【问题讨论】:

    标签: python typeerror


    【解决方案1】:

    看看:

    board = []
    row = ['O'] * 5 #<<<<determine the board size here 
    joined_O = '  '.join(row)
    
    • board 是一个列表。
    • row 是一个列表。
    • joined_O 是由 row 的元素串联而成的字符串。

    与:

    for i in range(5):  #<<<<determine the board size here
        board.append(joined_O)
        print(joined_O)
    

    board 现在是一个字符串列表

    所以

    board[int(missile_row)][int(missile_col)] = 'X'
    

    不是一个有效的命令,因为它试图修改板列表中的字符串而不是二维列表中的元素。在 Python 中,字符串是不可变的,因此您不能就地更改它们的字符。

    简而言之,board 不是代码中的二维列表,而是字符串列表。

    【讨论】:

    • 非常感谢您的回答!我不知道加入它们会使它们变成一个字符串。我现在明白为什么我不能用 X 代替 O 了,所以谢谢你!
    【解决方案2】:
    for i in range(5): #<<<<determine the board size here
        board.append(joined_O)
    

    这对我来说看起来不对。您应该将列表附加到board,而不是字符串。我猜你以前有类似的东西:

    for i in range(5):
        board.append(row)
    

    这至少是正确的类型。但是你会遇到奇怪的错误,当你错过一艘船时,会出现五个 X 而不是一个。这是因为每一行都是同一行;对其中一个进行更改会更改所有这些。您可以通过每次使用切片技巧复制该行来避免这种情况。

    for i in range(5): #<<<<determine the board size here
        board.append(row[:])
    

    现在您的 Xes 应该可以正确分配了。但是 print(board) 在你的 else 块中会有点难看。您可以使用几个快速连接很好地格式化它而无需括号和引号:

    else:
        print('Missile missed the target')
        board[int(missile_row)][int(missile_col)] = 'X'
        print("\n".join("  ".join(row) for row in board))
    

    现在你得到了一些相当不错的输出。

    Shoot missile to the ship
    row   : 1
    column: 1
    Missile missed the target
    O  O  O  O  O
    O  X  O  O  O
    O  O  O  O  O
    O  O  O  O  O
    O  O  O  O  O
    

    【讨论】:

    • 大哥,你只是把他代码里的bug都修好了,让他失去了学习python的机会。
    • 也许...但是编程的好处是将来总会有更多的错误/学习机会:-)
    • @Wajahat 不过,他确实在这里做了一些很好的教学——并且至少分解了代码以消除复制粘贴整个程序的机会。
    • 嗨!感谢您抽出时间来回答这个问题。我有几个问题,因为我仍然不明白其中的一些。 1. 如果我不使用切片技巧,为什么我在板列表中添加五次后每一行仍然是同一行?这是否意味着我将 5 个不同的列表添加到空列表中?我尝试过使用切片技巧,它奏效了,但我仍然对它的不同之处感到困惑。
    • 2.我之所以使用joined_o变量,是为了让棋盘从一开始就没有引号,而不仅仅是最后一点。您是否在末尾加入行以使它们不会成为字符串?我打算重复使用输入功能,所以如果板变成字符串列表,我不可能在板上放另一个“X”,对吗?如果您不明白我的意思,请告诉我,以便我详细说明。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    • 2011-07-26
    • 2015-07-28
    相关资源
    最近更新 更多