How To Loop Through A Set, While Removing Items From The Set In Python 3
Solution 1:
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 likedefpreload(player):
player.preloadVideo()
a.remove(player)
for player inlist(a):
preload(player) # N.B. pass player, not 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
).
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 likedefpreload(player):
return player.preloadVideo() # assume that this returns booleanfor player inlist(a):
if preload(player):
a.remove(player)
iflen(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.
Solution 2:
There is no need to loop over your list 2 time! as you said, it will raise a size changed
error.So instead you can use pop
property of set
and list
to get those items which return the value and remove it from your data structure.For a list you can pass the 0 index to pop
in each iteration also as a more pythoinc way you can use while
instead of for
when you want to remove item from your data structure :
a = [mp1, mp2 mp3]
while a:
preload(a.pop(0))
But for set
the pop doesn't accept the index:
a = set([mp1, mp2 mp3])
while a:
preload(a.pop())
Example :
>>>defpreload(i):...print i...>>>a=[1,2,3]>>>while a:... preload(a.pop(0))...
1
2
3
>>>a
[]
>>>a={1,2,3}>>>while a:... preload(a.pop())...
1
2
3
>>>a
set([])
Solution 3:
but would like return a bit in the future.
If you want to call the preload function asynchronously, I’d use the multiprocessing module:
from multiprocessing import Pool
a = set([mp1, mp2, mp3])
defpreload(player):
try: # Change it to if/else depending on your type of error handling
player.preload()
except:
return player
p = Pool(5) # uses 5 threads to do the computation, change it accordingly
uninitialized = {players for players in p.map(preload, a) if player isnotNone}
p.close()
Post a Comment for "How To Loop Through A Set, While Removing Items From The Set In Python 3"