在Python中遍历列表时删除项

5 投票
4 回答
18473 浏览
提问于 2025-04-17 03:13

我正在为一个比赛应用写一个循环赛算法。

当玩家人数是奇数时,我会在玩家列表中添加一个 'DELETE'。但是,后来当我想从日程列表中删除所有包含 'DELETE' 的项目时,总是有一个没被删除掉。请看看我的代码——这个问题很简单,我想这和列表有关;我就是看不出来问题出在哪里。

"""
Round-robin tournament:
1, 2, 3, 4, | 5, 6, 7, 8    =>  1, 2, 3, 4  => rotate all but 1 =>  1, 5, 2, 3  => repeat =>    1, 6, 5, 2  ...
                    5, 6, 7, 8              6, 7, 8, 4          7, 8, 4, 3
in every round pick l1[0] and l2[0] as first couple, after that l1[1] and l2[1]...
"""

import math

lst = []
schedule = []
delLater = False

for i in range(3):                  #make list of numbers
    lst.append(i+1)

if len(lst) % 2 != 0:               #if num of items is odd, add 'DELETE'
    lst.append('DELETE')
    delLater = True


while len(schedule) < math.factorial(len(lst))/(2*math.factorial(len(lst) - 2)): #!(n)/!(n-k)

    mid = len(lst)/2

    l1 = lst[:mid]
    l2 = lst[mid:]

    for i in range(len(l1)):            
        schedule.append((l1[i], l2[i]))         #add lst items in schedule

    l1.insert(1, l2[0])             #rotate lst
    l2.append(l1[-1])
    lst = l1[:-1] + l2[1:]


if delLater == True:                #PROBLEM!!! One DELETE always left in list
    for x in schedule:
        if 'DELETE' in x:
            schedule.remove(x)

i = 1
for x in schedule:
    print i, x
    i+=1

4 个回答

4

在遍历一个列表的时候,如果想要删除其中的元素,最好是从后往前进行操作:

if delLater == True:
    for x in schedule[-1::-1]):
        if 'DELETE' in x:
            schedule.remove(x)

还有一个更好的方法是使用列表推导式:

schedule[:] = [item for item in schedule if item != 'DELETE']

现在,你可以直接用 schedule = 来替代 schedule[:] =,这两者有什么不同呢?举个例子:

schedule = [some list stuff here]  # first time creating
modify_schedule(schedule, new_players='...') # does validation, etc.

def modify_schedule(sched, new_players):
    # validate, validate, hallucinate, illustrate...
    sched = [changes here]

到这个时候,modify_schedule 所做的所有修改都消失了。为什么呢?因为它没有直接修改原来的列表,而是把名字 sched 重新指向了一个新的列表,这样原来的列表依然和调用者中的名字 schedule 绑定在一起。

所以,是否使用 list_object[:] = 取决于你是否希望其他与这个列表绑定的名字也能看到这些变化。

7
schedule[:] = [x for x in schedule if 'DELETE' not in x]

可以看看其他关于在遍历列表时删除元素的问题。

3

在遍历一个列表的时候,不要修改这个列表:

for x in schedule:
    if 'DELETE' in x:
        schedule.remove(x)

可以试试这样做:

schedule[:] = [x for x in schedule if 'DELETE' not in x]

想了解更多信息,可以查看 如何在遍历时从列表中移除项目?

撰写回答