无法弄清楚如何在此 Python 代码中重新分配列表列表中的元素
Can't figure out how to reassign an element in a list of lists in this Python code
我了解访问列表列表中的元素通常是如何工作的。我知道如果你有一个列表 L = [['a', 'b'], ['c', d'],['e', 'f']]
,你可以使用 L[0][0]
访问 'a'。不过,我不确定为什么同样的事情在以下战舰游戏代码中不起作用:
from random import randint
from random import choice
# make a 5x5 board
board = []
row = ['O']*5
for x in range(5):
board.append(row)
def print_board():
for item in board:
print ' '.join(item)
#check if input falls within 5x5 grid
def check_valid(guess_row, guess_column):
return guess_row in range(5) and guess_column in range(5)
#return True- is valid choice, return False- not valid choice
#check that the input hasn't been guessed previously
def check_repeat(guess_row, guess_column):
return board[guess_row][guess_column] != 'O'
#return True- repeat, reurn False- new
#check if input is a correct answer
def check_correct(guess_row, guess_column):
return (guess_row, guess_column) == (row1, col1) or (guess_row, guess_column) == (row2, col2)
#return True- is correct, return False- is not correct
#place a 2-position ship
while True:
#pick random place to start
row1 = randint(0,4)
col1 = randint(0,4)
#choose adjacent second position
move_direction = choice(['north', 'south', 'east', 'west'])
if move_direction == 'north':
row2 = row1 - 1
col2 = col1
elif move_direction == 'south':
row2 = row1 + 1
col2 = col1
elif move_direction == 'east':
row2 = row1
col2 = col1 + 1
else: # must be west
row2 = row1
col2 = col1 - 1
#check that the second position is valid, else pick new values
if row2 in range(5) and col2 in range(5):
break
positions_left = 2 #how many points player needs to hit
#you now have a ship at coordinates (row1, col1), (row2, col2)
turns = 5
#the gameflow itself:
print 'let\'s play battleship!'
while turns > 0:
print 'You have %i turns remaining.' % turns
print_board()
guess_row = int(raw_input('Guess a row: ')) - 1 #-1 to account for python 0-indexing
guess_column = int(raw_input('Guess a column: ')) - 1
if check_valid(guess_row, guess_column) == False:
print 'Sorry, those aren\'t valid coordinates'
else: #continue game if valid
turns -= 1
if check_repeat(guess_row, guess_column): #old guess
print 'You seem to have guessed that already.'
turns += 1 #don't count this turn
elif check_correct(guess_row, guess_column):
print 'Hit!'
board[guess_row][guess_column] = '!'
positions_left -= 1
if positions_left == 0:
'You sunk the battleship!'
turns = 0 #stops game
else:
print 'You can sink this ship in %i more hits!' % positions_left
else:
board[guess_row][guess_column] = 'X'
print 'Sorry, you missed!'
问题发生在评估玩家的猜测后,我尝试将 'O' 重新分配给 '!' (表示命中)或 'X'(表示未命中)。这应该发生在:
elif check_correct(guess_row, guess_column):
print 'Hit!'
board[guess_row][guess_column] = '!'
并在:
else:
board[guess_row][guess_column] = 'X'
print 'Sorry, you missed!'
相反,整个列最终都被重新分配给了该值。因此,当玩家猜测第 1 行第 1 列时,该猜测被解释为 guess_row = 0, guess_column = 0
。
我希望 board 的新值变成:
[['X', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O'],['O', 'O', 'O', 'O',
'O'],['O', 'O', 'O', 'O', 'O'],['O', 'O', 'O', 'O', 'O']]
而是变成:
[['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O',
'O'],['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O', 'O']]
这真的很奇怪,因为当我提取一小段代码并尝试做这件事时,它工作正常,但当我尝试将其作为整个代码。
问题是您在每次迭代时将相同的 row
变量添加到板中。您应该添加一个新行,如下所示:
board = []
for _ in range(5):
board.append(['O'] * 5)
您的问题在这里:
row = ['O']*5
for x in range(5):
board.append(row)
由于上面的板将包含对行的 5 个引用,即相同的列表。这样改一个存,就会改所有的文件。您需要复制行,例如
for x in range(5):
board.append(row[:])
希望对您有所帮助。
我了解访问列表列表中的元素通常是如何工作的。我知道如果你有一个列表 L = [['a', 'b'], ['c', d'],['e', 'f']]
,你可以使用 L[0][0]
访问 'a'。不过,我不确定为什么同样的事情在以下战舰游戏代码中不起作用:
from random import randint
from random import choice
# make a 5x5 board
board = []
row = ['O']*5
for x in range(5):
board.append(row)
def print_board():
for item in board:
print ' '.join(item)
#check if input falls within 5x5 grid
def check_valid(guess_row, guess_column):
return guess_row in range(5) and guess_column in range(5)
#return True- is valid choice, return False- not valid choice
#check that the input hasn't been guessed previously
def check_repeat(guess_row, guess_column):
return board[guess_row][guess_column] != 'O'
#return True- repeat, reurn False- new
#check if input is a correct answer
def check_correct(guess_row, guess_column):
return (guess_row, guess_column) == (row1, col1) or (guess_row, guess_column) == (row2, col2)
#return True- is correct, return False- is not correct
#place a 2-position ship
while True:
#pick random place to start
row1 = randint(0,4)
col1 = randint(0,4)
#choose adjacent second position
move_direction = choice(['north', 'south', 'east', 'west'])
if move_direction == 'north':
row2 = row1 - 1
col2 = col1
elif move_direction == 'south':
row2 = row1 + 1
col2 = col1
elif move_direction == 'east':
row2 = row1
col2 = col1 + 1
else: # must be west
row2 = row1
col2 = col1 - 1
#check that the second position is valid, else pick new values
if row2 in range(5) and col2 in range(5):
break
positions_left = 2 #how many points player needs to hit
#you now have a ship at coordinates (row1, col1), (row2, col2)
turns = 5
#the gameflow itself:
print 'let\'s play battleship!'
while turns > 0:
print 'You have %i turns remaining.' % turns
print_board()
guess_row = int(raw_input('Guess a row: ')) - 1 #-1 to account for python 0-indexing
guess_column = int(raw_input('Guess a column: ')) - 1
if check_valid(guess_row, guess_column) == False:
print 'Sorry, those aren\'t valid coordinates'
else: #continue game if valid
turns -= 1
if check_repeat(guess_row, guess_column): #old guess
print 'You seem to have guessed that already.'
turns += 1 #don't count this turn
elif check_correct(guess_row, guess_column):
print 'Hit!'
board[guess_row][guess_column] = '!'
positions_left -= 1
if positions_left == 0:
'You sunk the battleship!'
turns = 0 #stops game
else:
print 'You can sink this ship in %i more hits!' % positions_left
else:
board[guess_row][guess_column] = 'X'
print 'Sorry, you missed!'
问题发生在评估玩家的猜测后,我尝试将 'O' 重新分配给 '!' (表示命中)或 'X'(表示未命中)。这应该发生在:
elif check_correct(guess_row, guess_column):
print 'Hit!'
board[guess_row][guess_column] = '!'
并在:
else:
board[guess_row][guess_column] = 'X'
print 'Sorry, you missed!'
相反,整个列最终都被重新分配给了该值。因此,当玩家猜测第 1 行第 1 列时,该猜测被解释为 guess_row = 0, guess_column = 0
。
我希望 board 的新值变成:
[['X', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O'],['O', 'O', 'O', 'O',
'O'],['O', 'O', 'O', 'O', 'O'],['O', 'O', 'O', 'O', 'O']]
而是变成:
[['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O',
'O'],['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O', 'O']]
这真的很奇怪,因为当我提取一小段代码并尝试做这件事时,它工作正常,但当我尝试将其作为整个代码。
问题是您在每次迭代时将相同的 row
变量添加到板中。您应该添加一个新行,如下所示:
board = []
for _ in range(5):
board.append(['O'] * 5)
您的问题在这里:
row = ['O']*5
for x in range(5):
board.append(row)
由于上面的板将包含对行的 5 个引用,即相同的列表。这样改一个存,就会改所有的文件。您需要复制行,例如
for x in range(5):
board.append(row[:])
希望对您有所帮助。