在for循环(python)中删除列表项时出现问题

problem Deleting list items in a for loop (python)

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

Possible Duplicate:
Remove items from a list while iterating in Python

嗨,我有一个问题,我在用python迭代一个列表时似乎不能删除项目,这里是我得到的:如果一个用户在for循环中被问到要删除的问题时输入n或n,那么标题应该被删除,问题是当它完成时,所有的项都还在那里,没有一项被删除…

1
2
3
4
5
6
7
8
9
10
    titles_list = ["English","Math","History","IT","Biology","Spanish"]

    for title in titles_list:
        print"Do you want to keep the title:", title ,"
 or Delete it ? Input Y for keep, N for Delete"

        Question = raw_input()
        if str(Question.upper) =="N":
            titles_list.remove(title)

print titles_list


下面的代码将解决您的问题。您必须迭代列表的一个副本。不能从正在迭代的列表中删除项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import copy

def main():
    titles_list = ["English","Math","History","IT","Biology","Spanish"]
    titles_list_orig = copy.deepcopy(titles_list)

    for title in titles_list_orig:
        print"Do you want to keep the title:", title ,"
 or Delete it? Input Y for keep, N for Delete"

        Question = raw_input()
        if str(Question.upper()) =="N":
            titles_list.remove(title)

    print titles_list


您的代码实际上有两个主要问题。

第一个问题是,您不是在调用upper方法,而是仅仅引用它。你需要像W00T在他的回答中那样(通过Question.upper()来称呼它)。

将一些诊断打印语句放入循环中是一个很好的方法来查看这一点(尤其是打印出str(Question.upper)(切线:Question是一个变量的坏名称,该变量保存了程序向用户询问的问题的答案)。

其次,从正在迭代的列表中删除已经看到的项将导致跳过值。您实际上不需要复制整个列表来处理这个问题——只需反向迭代就可以解决这个问题。

最后,有几个小的修饰点是,raw_input()接受一个提示性参数,因此您不需要单独的print语句,并且对字符串调用upper()本身将始终返回一个字符串:

1
2
3
4
5
6
7
8
9
10
11
titles_list = ["English","Math","History","IT","Biology","Spanish"]
prompt = ("Do you want to keep the title: {}
"

         "or Delete it? Input Y for keep, N for Delete:")

for title in reversed(titles_list):
    answer = raw_input(prompt.format(title))
    if answer.upper() =="N":
        titles_list.remove(title)

print titles_list


我认为您代码中的主要问题是不正确地使用了upper函数。修复后,您可以根据需要从列表中删除标题。您可以使用索引或值。这是为我剪掉的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/python

import string

titles_list = ["English","Math","Biology","IT","History"]
for title in titles_list:
  answer = raw_input("Do you want to keep this title %s, type y or n
"
% (title))
  if string.upper(answer) =="N":
    # i = titles_list.index(title)
    # del titles_list[i]
    titles_list.remove(title)
    print"now list is" , titles_list
print titles_list

请使用索引查看注释行。此外,还可以使用原始输入(提示)功能使代码更简洁。

您还需要考虑在您的列表中出现多个相同标题的情况,在这种情况下,我建议获取标题的所有索引,直到列表为空,并使用del(index)删除标题,因为上面给出的解决方案将只删除标题的第一次出现。


我知道已经有了一个答案,这里是另一种完整性的方法,并演示清单理解。

此方法获取一个列表,要求保留每个项,并返回一个新列表,不包括标记为删除的列表:

1
2
3
4
5
6
7
def delete_items(titles):
    deleted_items = []
    for title in titles:
        print('keep %s?' % title)
        if str(raw_input().upper()) == 'N':
            deleted_items.append(title)
    return [e for e in titles if e not in deleted_items]