【问题标题】:Iterate data structure while it is updated在更新时迭代数据结构
【发布时间】:2019-12-16 15:28:16
【问题描述】:

在python中迭代数据结构同时从结构中删除元素的正确方法是什么?

我想遍历 someList 结构并确保访问列表中的所有项目,只要它们在列表中,并在我迭代它时删除一些项目。但是我不明白为什么会跳过一些数字以及如何避免这种情况,分别。确保在列表中的每个元素没有被提前删除的情况下,实际上只看到一次。在示例中,我从未见过158

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)

输出:

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]

预期输出:

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]

注意:这与How to remove items from a list while iterating? 不是同一个问题,因为我不想在迭代之前过滤掉元素。

这两个修改条件只是示例,因为我确实会迭代图形数据结构,消耗当前元素并删除一些与当前元素具有特定关系的元素。

【问题讨论】:

  • 你为什么不想创建一个没有元素的新列表?您甚至可以通过切片 [:] 将新列表重新分配给原始列表
  • 如果您正在迭代更新list,您可以使用list.copy() 来完成。
  • 不要;通过添加您想要保留的元素来构建一个新列表,而不是从原始列表中删除您不想要的元素。
  • 我不想复制数据结构,因为它可能很大。我也不能只将所选项目添加到新结构中,因为我需要删除尚未访问的连接元素,以便以后不再访问它们。

标签: python yield


【解决方案1】:

正如其他人所说,如果您尝试在运行时修改列表,您将无法获得正确的迭代,因此请改用另一个列表来存储您要删除的内容,

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 存储要删除的成员而不是循环检查它们会给你预期的结果..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 2020-04-12
    相关资源
    最近更新 更多