在python中从列表中删除项,同时对其进行迭代

Delete item from list in Python while iterating over it

本问题已经有最佳答案,请猛点这里访问。

我正在为锦标赛应用程序编写循环算法。

当玩家数量为奇数时,我将'DELETE'添加到玩家列表中,但稍后,当我想从包含'DELETE'的日程表列表中删除所有项目时,我不能——总是留下一个。请看一下代码——问题很简单,我想是关于列表的;我就是看不到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
"""
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

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

请参阅有关在迭代列表时从列表中删除的其他问题。


要在遍历列表时从列表中删除元素,需要向后:

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

更好的选择是使用列表理解:

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

现在,你可以用schedule =代替schedule[:] =,有什么区别?一个例子是:

1
2
3
4
5
6
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[:] =取决于您是否希望将任何其他名称绑定到您的列表以查看更改。


在对列表进行迭代时,不应修改该列表:

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

相反,尝试:

1
schedule[:] = [x in schedule where 'DELETE' not in x]

有关详细信息,请参见在迭代时从列表中删除项


不要修改正在迭代的序列。

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