Python - list.remove 在列表上迭代时
Python - list.remove while iterating on the list
在 python 中,我遇到了 list.remove 方法的问题。它没有删除逻辑上必须存在的内容,并且列表中留下了大量内容。
import os
def removeAll(content):
for afile in content:
content.remove(afile)
return content
content = removeAll(os.listdir("C:\Windows\System32"))
print(content)
但是如果我要在没有循环的情况下删除单个内容
content.remove(content[123]) #If this string hasn't already been removed.
它会起作用的。
这是为什么呢?处理大型列表的理想替代方法是什么?
这不是错误。请参阅 Remove items from a list while iterating 以了解如何完美地做到这一点。
列表是一种可变数据类型。如果从中删除元素,列表的长度(可能还有元素的索引)将会改变。在你的第二个例子中,如果你在删除之前和之后打印内容的长度,你会看到不同之处,因为你没有假设旧索引和长度对列表有效。
考虑以下示例以了解有关何时发生此异常的更多信息:
>>> content = range(4)
>>> content
[0, 1, 2, 3]
>>> len(content)
4
>>> count = 0
>>> length = len(content)
>>> while count < length:
... print count, length, content, len(content)
... content.remove(content[count])
... count += 1
...
0 4 [0, 1, 2, 3] 4
1 4 [1, 2, 3] 3
2 4 [1, 3] 2
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
IndexError: list index out of range
很明显,你迭代的长度是一个常数,但是count的值只是对应于列表中不再存在的索引位置。
要解决列表的这种可变性质,您可以从列表的末尾删除元素:
>>> content = range(4)
>>> count = len(content) - 1
>>> while count >= 0:
... print count, length, content, len(content)
... content.remove(content[count])
... count -= 1
...
3 4 [0, 1, 2, 3] 4
2 4 [0, 1, 2] 3
1 4 [0, 1] 2
0 4 [0] 1
>>> print content
[]
或者您可以 pop
/ remove
总是第一个元素,正如其他答案所指出的那样。
您可以尝试使用 pop
或 remove
。
for file in range(len(content)):
content.pop(0) # return 0th element in every iteration.
或
for file in range(len(content)):
content.remove(content[0]) #just removes the oth element in every iteration
如果你想清空列表,将所有内容切片并替换为空:
content[:] = []
在 python 中,我遇到了 list.remove 方法的问题。它没有删除逻辑上必须存在的内容,并且列表中留下了大量内容。
import os
def removeAll(content):
for afile in content:
content.remove(afile)
return content
content = removeAll(os.listdir("C:\Windows\System32"))
print(content)
但是如果我要在没有循环的情况下删除单个内容
content.remove(content[123]) #If this string hasn't already been removed.
它会起作用的。 这是为什么呢?处理大型列表的理想替代方法是什么?
这不是错误。请参阅 Remove items from a list while iterating 以了解如何完美地做到这一点。
列表是一种可变数据类型。如果从中删除元素,列表的长度(可能还有元素的索引)将会改变。在你的第二个例子中,如果你在删除之前和之后打印内容的长度,你会看到不同之处,因为你没有假设旧索引和长度对列表有效。
考虑以下示例以了解有关何时发生此异常的更多信息:
>>> content = range(4)
>>> content
[0, 1, 2, 3]
>>> len(content)
4
>>> count = 0
>>> length = len(content)
>>> while count < length:
... print count, length, content, len(content)
... content.remove(content[count])
... count += 1
...
0 4 [0, 1, 2, 3] 4
1 4 [1, 2, 3] 3
2 4 [1, 3] 2
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
IndexError: list index out of range
很明显,你迭代的长度是一个常数,但是count的值只是对应于列表中不再存在的索引位置。
要解决列表的这种可变性质,您可以从列表的末尾删除元素:
>>> content = range(4)
>>> count = len(content) - 1
>>> while count >= 0:
... print count, length, content, len(content)
... content.remove(content[count])
... count -= 1
...
3 4 [0, 1, 2, 3] 4
2 4 [0, 1, 2] 3
1 4 [0, 1] 2
0 4 [0] 1
>>> print content
[]
或者您可以 pop
/ remove
总是第一个元素,正如其他答案所指出的那样。
您可以尝试使用 pop
或 remove
。
for file in range(len(content)):
content.pop(0) # return 0th element in every iteration.
或
for file in range(len(content)):
content.remove(content[0]) #just removes the oth element in every iteration
如果你想清空列表,将所有内容切片并替换为空:
content[:] = []