问题在for循环中删除列表项(python)[重复]

Posted

技术标签:

【中文标题】问题在for循环中删除列表项(python)[重复]【英文标题】:problem Deleting list items in a for loop (python) [duplicate] 【发布时间】:2011-07-21 01:42:53 【问题描述】:

可能重复:Remove items from a list while iterating in Python

您好,我遇到了一个问题,我似乎无法在 python 中遍历列表时删除项目, 这就是我所得到的:如果用户在 for 循环中询问要删除的问题时输入 n 或 N,则应删除标题,问题是当所有项目都完成后,项目仍然存在并且没有被删除...

    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

【问题讨论】:

也是Python strange behavior in for loop or lists的副本。而且列表切片解决方案似乎更pythonic。 【参考方案1】:

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

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

【讨论】:

谢谢:我使用拼接导致它的线条更少,但你让我需要复制它谢谢 不需要复制它,只需反向迭代它,这样删除就不会影响您在迭代时看到的项目。 @ncoghlan - 您能否详细说明您的答案。我不清楚。 deepcopy 的替代方案,您也可以使用orig = list(titles) 复制列表:-) @Wesley:同意,事实上这在一般情况下更合适(即对于字符串以外的东西),因为它是浅拷贝而不是深拷贝。我们不需要titles_list 内容的副本。【参考方案2】:

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

首先是您没有调用upper 方法,而只是引用它。您需要像 w00t 在他的回答中那样实际调用它(通过Question.upper())。

在循环中放入一些诊断打印语句将是一个很好的查看方式(尤其是打印出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

【讨论】:

您可能想提一下,新样式的字符串格式仅适用于 python 2.7 及更高版本。 实际在2.6或更高版本中可用 但是是的,如果你需要使用2.5或更早的版本,那么格式字符串中的需要替换为%s,格式化命令本身就变成了prompt % title。跨度> 【参考方案3】:

我认为您代码中的主要问题是不正确地使用了上层函数。修复后,您可以随意从列表中删除标题。您可以使用索引或值。这是对我有用的代码片段

#!/usr/bin/python 导入字符串 title_list = [“英语”、“数学”、“生物学”、“IT”、“历史”] 对于titles_list 中的标题: answer = raw_input("你想保留这个标题 %s,输入 y 或 n\n" % (title)) 如果 string.upper(answer) == "N": # i =titles_list.index(title) # 删除标题列表[i] 标题列表.删除(标题) 打印“现在列表是”,titles_list 打印titles_list

请使用索引查看注释行。此外,您可以使用 raw_input(prompt) 功能使您的代码更简洁。

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

【讨论】:

无需使用 string 模块 - answer.upper() 工作正常。但是,您是否真的尝试过,看看每次按下n 时会发生什么?您将没有机会从列表中删除 "Math""IT"【参考方案4】:

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

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

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]

【讨论】:

以上是关于问题在for循环中删除列表项(python)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Python3基础 使用for循环 删除一个列表中的重复项

从 For 循环中删除重复项

使用循环从字符数组列表中删除重复项? [复制]

从 Vue 中的 v-for 列表中删除重复项

使用带有 JavaScript 的 for 循环时,将新列表项添加到 <ul> 项 [重复]

从 Python 列表中删除重复项