有效删除和检查列表

时间:2012-08-01 11:10:55

标签: python list for-loop indexing

现在我正在尝试将战舰棋盘游戏作为练习,而且我一直在使用类似于一些misc独立功能的类。以下所有内容都是独立的。我无法绕过它,如果我按照从列表的最后到第一个顺序攻击船只,这是有效的,但是如果你按照任何其他顺序进行攻击,则说明列表索引不存在。请帮忙。

基本上我的系统是每当一艘船“被击中”时(该移动与shipList中的一个位置相同)然后它会添加一个命中列表。这些函数的作用是检查hitList中的任何项目是否与船舶的已知位置相对应...在制作船舶对象时在单独的列表中创建。我一直试图让这项工作持续2天

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

我是不是错了?我应该在物理上删除列表吗?

由于

4 个答案:

答案 0 :(得分:1)

答案与问题Delete item in a list using a for-loop相同:

向后迭代:

for j in range(len(shipList) - 1, -1, -1):

答案 1 :(得分:0)

如果我理解得很清楚,你的hitlist包含所有命中(意思是,你不会在每次移动时检查):如果是这样,gecco是正确的症状:你在迭代时不能删除列表中的元素它(使索引无效)。但是反转列表并不会解决这个问题,因为如果你从头到尾沉没船只会遇到同样的问题。

如果您不想过多地更改代码,请将del shipList[j]替换为shipList[j][0] = None(您不删除列表元素,因此迭代仍然有效)然后只需重新定义函数{{1 }}:

isGameOver

答案 2 :(得分:0)

您遇到的错误已在@gecco回答中解释。

避免使用嵌套循环可以使代码易于理解。

例如,以下函数是错误的,因为它只会检查列表中的第一个元素。

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])]

答案 3 :(得分:-1)

很抱歉,我无法为您提供解决方案代码,因为您没有提供足够的信息或代码供我修复。但我提供的代码示例可能有助于您理解列表。

#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

我希望这有帮助