Remove函数更改不相关for循环(Python)的元素
我尝试删除数据库中小于所选字符I的所有字符。数据库是字符列表的列表Remove函数更改不相关for循环(Python)的元素,python,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(c
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']]
虽然我没有更改迭代列表,但为什么打印的字符会更改?调试后:
问题不是因为if语句,而是因为remove更改了索引
让mt证明:
- 在第一次迭代删除后,列表将为:
["B", "D"]
您的索引将是1,因为
“B”
将被忽略。您的问题与您复制列表数据库有关
根据:
浅复制构造一个新的复合对象,然后(尽可能)向其中插入对原始对象的引用
深度副本构造一个新的复合对象,然后递归地将在原始副本中找到的对象的副本插入其中
如果您深度复制copy.deepcopy(x)
您的列表,那么您将得到一个单独的对象,它不是另一个对象的引用,而是一个完整的副本。正如其他答案中已经提到的,您的代码有两个问题:一个是浅复制,另一个是修改正在迭代的列表。然而,您甚至不需要所有这些复杂性。在您的情况下,保留“好”项目比删除“坏”项目更便宜:
顺便说一下,条件chartest
不是数据库的副本。是的,但这是一个肤浅的复制品。它包含对原始内部列表的引用。你需要一个深度副本。我担心改变我正在迭代的矩阵可能会解释这种奇怪的行为。我只是检查了没有所有副本的代码,它也一样。请阅读答案,其中至少有一个解释了如何制作深度副本。深度副本如何修复了此问题?可能的副本也请参阅
["B", "D"]
def project(database, i):
return [[item for item in lst if item >= i] for lst in database]
print(project(a, 'C'))
# [['D'], ['C', 'D']]