删除函数更改不相关的 for 循环 (Python) 的元素



我尝试删除数据库中小于所选字符 i 的所有字符。数据库是字符列表的列表。

def project(database, i):
test = database.copy()
for idx,lists in enumerate(database.copy()):
for char in lists:
print(char)
if char <= i:
test[idx].remove(char)
return test
a = [['A','B','D'],['A','B','C','D']]
print(project(a, 'C'))

Output:
A D A C
[['B', 'D'], ['B', 'D']]

不知何故,代码从不检查"B",尽管它在列表中。没有 if 条件 + 删除行(第 5-6 行)的相同代码执行以下操作:

Output:
A B D A B C D
['A', 'B', 'D'], ['A', 'B', 'C', 'D']]

为什么打印的字符会改变,而我没有改变迭代列表?

调试后:

问题不是因为您的 if 语句,而是因为删除更改索引。

让我们 mt 证明:

  • 第一次迭代删除 A 后,列表将是:

    ["B", "D"]
    

您的索引将为 1,因此"B"将被忽略。

您的问题与您复制列表database有关。

根据 python.org 文档:

浅拷贝构造一个新的复合对象,然后(尽可能)在其中插入对原始对象中找到的对象的引用。

深层副本构造一个新的复合对象,然后递归地将原始对象中发现的对象的副本插入其中。

如果您copy.deepcopy(x)列表中进行深度复制,那么您将获得一个单独的对象,该对象不是另一个对象的引用,而是完整副本。

正如在其他答案中已经提到的,您的代码有两个问题:一个是浅拷贝,另一个是修改正在迭代的列表。但是,您甚至不需要所有这些复杂性。在您的情况下,保留"好"项目比删除"坏"项目便宜:

def project(database, i):
return [[item for item in lst if item >= i] for lst in database]
print(project(a, 'C'))
# [['D'], ['C', 'D']]

顺便说一下,条件char <= i删除小于或等于i的项目,而不仅仅是小于i

最新更新