如何在Python 3中从集合中删除项目的同时遍历集合 [英] How to loop through a set, while removing items from the set in Python 3

查看:76
本文介绍了如何在Python 3中从集合中删除项目的同时遍历集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的情况:

我要调用"preload"函数的movieplayer对象有一个list/set(无关紧要).该预加载函数可以立即返回,但将来希望返回.

I have a list/set (doesn't matter which) of movieplayer objects that I want to call a "preload" function on. This preload function could return immediately but would like return a bit in the future.

我想存储这个电影播放器​​的集合,指示它们尚未预加载,然后遍历它们,调用preload函数. preload函数在返回时会将它们从集合中删除(所以我会知道它们何时都已预加载).

I want to store this collection of movieplayers, indicating that they have not been preloaded yet, then loop through them, calling the preload function. The preload function, when returned, would remove them from the collection (so I would know when they are all preloaded).

但是,我认为因为python正在等待preload函数,然后删除播放器,所以我得到了set size changed during iteration error.

However, I think because python is waiting for the preload function, then removing the player, I am getting a set size changed during iteration error.

嘿,这是我代码的简化版本,我希望能找到一种解决此问题的方法.

Hey is a simplified version of my code, I would appreciate a way to navigate this issue.

a = set([mp1, mp2 mp3])
for player in a:
    preload(player)

# preload would be something like
def preload(player):
    player.preloadVideo()
    a.remove(player)
    # This is where I believe the error gets generated.

我能想到的唯一解决方案是将set a制成copy,然后对其进行迭代,但是我不确定这是否是正确的方法甚至是可行的.

The only solution that I can think of would be to make a copy of the set a, and then iterate through that, but I am not sure if that is the right way to do it or would even work.

推荐答案

您可以通过遍历集合的副本来解决此问题.我在这里使用list()

You can fix it by iterating over a copy of the set. I've used list() here:

a = set(['mp1', 'mp2', 'mp3'])

# preload would be something like
def preload(player):
    player.preloadVideo()
    a.remove(player)

for player in list(a):
    preload(player)    # N.B. pass player, not a

但是,这不是一个很好的设计.一方面,全局变量a是从preload()函数中引用的.此外,for循环遍历集合中的所有元素,依次将每个元素传递到preload(),因此不必检查a中每个player的成员资格.最后,preload()应该执行预加载播放器所需的所有操作,但它不负责维护外部数据结构(a).

This, however, is not a great design. For one thing the global variable, a is referenced from within the preload() function. Furthermore, the for loop iterates over all elements of the set passing each in turn to preload(), so it is not necessary to check membership of each player in a. Lastly, preload() should perform whatever is required to preload the player, but it should not be responsible for maintaining an external data structure (a).

更好的设计是preload()返回一个布尔值,该布尔值指示预加载是否成功.然后,可以在预加载功能之外删除成功加载的播放器:

A better design is for preload() to return a boolean indicating whether the preload was successful or not. Removal of a successfully loaded player can then be done outside of the preload function:

a = set(['mp1', 'mp2', 'mp3'])

# preload would be something like
def preload(player):
    return player.preloadVideo()    # assume that this returns boolean

for player in list(a):
    if preload(player):
        a.remove(player)

if len(a):
    print "{} player(s) failed to preload: {}".format(len(a), a)        
else:
    print "All players successfully preloaded"

此代码只会在成功预加载播放器后将其删除.

This code will only remove a player once it has been successfully preloaded.

这篇关于如何在Python 3中从集合中删除项目的同时遍历集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆