python - Iterate data structure while it is updated
问题描述
What is the correct way to iterate over a data structure in python while elements are removed from the structure at the same time?
I want to iterate over the someList
structure and make sure to reach all items in the list as long as they are in the list and remove some of the items while I iterate it. But I don't understand why some numbers are skipped and how I can avoid this, resp. make sure to actually see each element in the list exactly once, under the condition, that it was not removed in advance. In the example I never saw 1
, 5
, and 8
class someList():
def __init__(self):
self.list = list(range(0,10))
def getData(self):
for i in self.list:
print(i)
yield i
thing = someList()
for a in thing.getData():
print("we reached:", a)
if a % 2 == 1:
print("remove", a)
thing.list.remove(a)
elif (a * 2) in thing.list:
print("remove double a:", a, " a*2:", a * 2)
thing.list.remove(a*2)
print(thing.list)
Output:
0
we reached: 0
remove double a: 0 a*2: 0
2
we reached: 2
remove double a: 2 a*2: 4
3
we reached: 3
remove 3
6
we reached: 6
7
we reached: 7
remove 7
9
we reached: 9
remove 9
[1, 2, 5, 6, 8]
Intended Output:
0
we reached: 0
remove double a: 0 a*2: 0
1
we reached: 1
remove 1
2
we reached: 2
remove double a: 2 a*2: 4
3
we reached: 3
remove 3
5
we reached: 5
remove 5
6
we reached: 6
7
we reached: 7
remove 7
8
we reached: 8
9
we reached: 9
remove 9
[2, 6, 8]
Note: this is not the same question as How to remove items from a list while iterating? because I do not want to filter out the elements before I iterate.
The two modifying conditions are just examples as I indeed do iterate over a graph data structure, consume the current element and remove some elements that have a specific relation to the current element.
解决方案
正如其他人所说,如果您尝试在运行时修改列表,您将无法获得正确的迭代,因此请使用另一个列表来存储您要删除的内容,
class someList():
def __init__(self):
self.list = list(range(0,10))
def getData(self):
for i in self.list:
print(i)
yield i
thing = someList()
rem_list=[]
for a in thing.getData():
print("we reached:", a)
if a in rem_list:
pass
elif a % 2 == 1:
print("remove", a)
rem_list.append(a)
elif (a * 2) in thing.list:
print("remove double a:", a, " a*2:", a * 2)
rem_list.append(2*a)
thing.list=[x for x in thing.list if x not in rem_list]
print(thing.list) #outputs [2, 6, 8]
使用 rem_list 存储要删除的成员而不是循环检查它们会给你预期的结果..
推荐阅读
- sql - 从一组列中查找第二大值
- javascript - 我需要使用 HTML、CSS 和 JavaScript 来实现这一点——任何帮助都会很棒
- javascript - webpack 代码拆分是否适用于 react-native?
- cygwin - 什么cygwin包包含zipcmp命令
- javascript - 用于检查日期格式文本的正则表达式未按预期工作
- python - 从包含有向图的 .dot 文件创建一个图形
- laravel - 如何将两个中间件分配给同一组路由。拉拉维尔
- laravel - Laravel 和 vue:require 未定义
- r - 在 R 中重新组织数据框(总概率)
- python - python cgi中防止路径遍历的代码