2011-03-23 65 views
6

可能重复:
Remove items from a list while iterating in Python问题删除列表项的for循环(蟒蛇)

喜IM有一个问题,我似乎无法删除的项目,同时通过Python中的列表迭代, 这里是我已经有了:一个标题应删除,如果用户输入N或N当被问及在for循环中删除的问题,问题是,当它完成所有的项目都依然存在,有没有被删除...

titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"] 

    for title in titles_list: 
     print "Do you want to keep the title:", title , "\n 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 
+0

同样([在for循环或列表的Python奇怪的行为]的DUP HTTP ://stackoverflow.com/q/742371/76705)。列表切片解决方案似乎更加pythonic。 – 2011-03-23 07:54:02

回答

10

下面的代码将解决您的问题。您必须遍历列表的副本。您无法从正在迭代的列表中删除项目。

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 , "\n 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 
+0

谢谢:D我使用拼接导致其较少的行,但是ü导致我需要复制它,谢谢 – RY4N 2011-03-23 06:53:10

+0

没有必要复制它,只是反向迭代它,所以删除不会影响你在迭代时看到的项目。 – ncoghlan 2011-03-23 07:05:36

+1

@ncoghlan - 请你详细解答你的答案。对我不清楚。 – Sumod 2011-03-23 07:09:25

7

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

首先是你不是调用upper方法,但只是引用它。实际上你需要调用它(通过Question.upper())作为w00t在他的回答一样。

把你的循环里面的一些诊断打印语句会一直看到(尤其是打印出str(Question.upper))的好方法(正切:Question是用于保存回答一个问题问的程序变量的坏名声用户)

其次,从你迭代将导致跳过值的列表中删除已经看过的项目。你实际上并不需要复制整个列表处理这个 - 只是遍历它是反向足以解决问题。

最后,一对夫妇的未成年人的美容点是raw_input()接受提示参数,所以你不需要单独的打印语句,并在一个字符串调用upper()将本身总是返回一个字符串:

titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"] 
prompt = ("Do you want to keep the title: {}\n" 
      "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 
+0

您可能想要提及的是,新的样式字符串格式只能在python 2.7及更高版本中使用。 – 2011-03-23 07:34:37

+0

它实际上在2.6或更高版本中可用 – ncoghlan 2011-03-23 11:02:56

+0

但是,如果您需要使用2.5或更早版本,那么格式化字符串中的“{}”需要被替换为“%s”,并且格式化命令本身变为'prompt% title'。 – ncoghlan 2011-03-23 11:47:05

1

我认为你的代码中的主要问题是上层函数的不正确使用。一旦你修好了,你可以随意从列表中删除标题。您可以使用索引或值。这里是代码剪切,我工作

 
#!/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\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 

请参阅使用索引注释行。此外,您还可以使用的raw_input(提示)功能让你的代码更简洁。

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

+0

不需要使用'string'模块 - 'answer.upper()'工作得很好。然而,你是否真的试过这个,看看每次按下'n'时会发生什么?您将不会被提供从列表中删除“Math”或“IT”的机会。 – ncoghlan 2011-03-23 11:49:33

0

我知道有一个答案已经,这里是完整的另一种方式,并展示列表理解。

此方法需要一个清单,要求保持每个项目,并返回不包括标记为删除的那些新的列表:

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]