Python 高效地删除和检查列表
现在,我正在尝试将战舰棋盘游戏作为练习,并且我在大部分情况下使用了带有一些杂项独立函数的类。下面的所有内容都是独立的。我不知道该怎么做,如果我按照列表中从最后一个到第一个的顺序攻击飞船,这是可行的,但是如果你按照其他顺序攻击飞船,它就会说列表索引不存在。请帮忙 基本上,我的系统是,每当一艘船被“击中”(移动位置与船舰列表中的位置相同),它就会添加一个命中列表。这些功能是检查hitList中的任何项目是否与船舶的已知位置相对应…在制作船舶对象时在单独的列表中创建。我两天来一直在努力工作Python 高效地删除和检查列表,python,list,for-loop,indexing,Python,List,For Loop,Indexing,现在,我正在尝试将战舰棋盘游戏作为练习,并且我在大部分情况下使用了带有一些杂项独立函数的类。下面的所有内容都是独立的。我不知道该怎么做,如果我按照列表中从最后一个到第一个的顺序攻击飞船,这是可行的,但是如果你按照其他顺序攻击飞船,它就会说列表索引不存在。请帮忙 基本上,我的系统是,每当一艘船被“击中”(移动位置与船舰列表中的位置相同),它就会添加一个命中列表。这些功能是检查hitList中的任何项目是否与船舶的已知位置相对应…在制作船舶对象时在单独的列表中创建。我两天来一直在努力工作 def c
def checkForSunk(shipList, hitList):
#Lists is something like this [[0,1],[0,2],[0,3]]
#ShipList[0] is list, [1] is name of ship
#ShipList is ALL ships.
print 'SHIPLIST : %s' % (shipList)
#[[[[0,1],[0,2],[0,3],[0,4],[0,5],[],[]], 'Destroyer'], [[[0,1],[0,2],[0,3],[0,4],[0,5],[],[]], 'Destroyer'], [[[0,1],[0,2],[0,3],[0,4],[0,5],[],[]], 'Destroyer']]
#[[[0,1],[0,2],[0,3],[0,4],[0,5],[],[]], 'Destroyer']
# 0 1
print 'HITLIST : %s ' % (hitList)
for j in range(len(shipList)):
for i in shipList[j][0]:
if i in hitList:
print 'True in ship # %s' % (shipList[j][1])
del shipList[j][0][shipList[j][0].index(i)] #Delete that part of the ship from the list.
#Check if there's any empty ships, and delete the ship if there are.
for j in range(len(shipList)):
print shipList[j] #Problem around here!!!!!!!!!!!!
if listIsEmpty(shipList[j][0]):
print '%s has been sunk!' % (shipList[j][1])
del shipList[j]
def isGameOver(shiplist):
if shiplist == []:
return True
else:
return False
def listIsEmpty(list):
for i in range(len(list)):
if list[i] != []: #If it finds anything thats not empty, return False. Else true
return False
else:
return True
我是不是完全错了?我应该实际删除列表吗
谢谢很抱歉,我无法向您提供解决方案代码,因为您没有提供足够的信息或代码供我为您修复。但是我提供了一些代码示例,它们可能会帮助您理解列表
#a list with 10 object
mylist = [1,2,3,4,5,6,7,8,9,10]
print mylist
>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#if i print the 6th object:
print mylist[5]
>>>
6
#if i delete an object from the end:
del mylist[9]
print mylist
>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9]
#as you can see, the item is gone, and the list only has 9 objects.
#if i print the 6th object:
print mylist[5]
>>>
6
#but if i delete an item from the middle
del mylist[4]
print mylist
>>>
[1, 2, 3, 4, 6, 7, 8, 9]
#i now have 8 objects as expected, but the objects location in the list has changed.
#if i print the 6th object:
print mylist[5]
>>>
7
我希望这有帮助答案与问题的答案相同: 向后迭代:
for j in range(len(shipList) - 1, -1, -1):
如果我能很好地理解,您的
命中列表包含所有命中(意思是,您不必在每次移动时都进行检查):如果是这样,gecco的症状是正确的:您不能在对列表进行迭代时删除列表中的元素(这会使索引无效)。但是,颠倒列表并不能解决这个问题,因为如果你从第一个到最后一个沉船,你也会遇到同样的问题
如果您不想太多地更改代码,请将del shipList[j]
替换为shipList[j][0]=None
(您不删除列表元素,因此迭代仍然有效),然后只需重新定义函数isGameOver
:
def isGameOver(shiplist):
ret = True
for ship in shiplist:
if shiplist[0] is not None:
ret = False
break
return ret
您遇到的bug已在@gecco-answer中解释过
避免使用嵌套循环可以使代码易于理解
例如,以下函数是错误的,因为它只检查列表中的第一个元素
def listIsEmpty(list):
for i in range(len(list)):
if list[i] != []: #If it finds anything thats not empty, return False. Else true
return False
else:
return True
它可以写成
def listIsEmpty(alist):
return not any(alist)
以及checkForSunk函数
#Check if there's any empty ships, and delete the ship if there are.
for j in range(len(shipList)):
print shipList[j] #Problem around here!!!!!!!!!!!!
if listIsEmpty(shipList[j][0]):
print '%s has been sunk!' % (shipList[j][1])
del shipList[j]
可以写成
# sometimes use filter can make thing easier.
shipList = [k for k in shipList if not listIsEmpty(k[0])]
看看这个问题:是的,但这会创建一个新列表,而不是在现有列表中循环(性能)--编辑:您是对的:reverse返回一个迭代器,而不是一个新列表。但请注意,在他的例子中,j是一个索引,而不是ship对象本身。。。因此,反向
方法在这里并没有真正的帮助——我认为你的情况和以前一样,如果你从第一个到最后一个沉船。。。