codyc4321
codyc4321

Reputation: 9682

remove items from set that pass a certain test python

I need to remove any items that have None value for a certain dict key in a python set. Given a simple set:

In [7]: z
Out[7]: {None, 1, 2}

In [8]: for item in z:
   ...:     if not item:
   ...:         z.remove(item)
   ...:         
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-8-680a51a37622> in <module>()
----> 1 for item in z:
      2     if not item:
      3         z.remove(item)
      4 

RuntimeError: Set changed size during iteration

I can't see why, but it won't let me remove objects during iteration. How can I run a dynamic truth check and remove items from sets? Thank you

Upvotes: 0

Views: 115

Answers (3)

Jared Goguen
Jared Goguen

Reputation: 9010

Rob has a good answer if you want to retain the structure of your code; otherwise, you can use a comprehension to do this in a single line.

example_set = {None, 1, 2}
filtered_set = {item for item in example_set if item}

print(filtered_set) # {1, 2}

If your logic is more complex than just if item, then it's probably better to keep the for loop.

Upvotes: 2

This error is very common when the for cycle is used to walk on a list or dictionary. The problem is that you intend change the content of the dictionary while you walk through of this.

In this case one solution is use a index for walk through of the dictionary, something like:

for i in range( len(dic) ):

But you are using SET, the SET object in python 3 have a method called discard that you can use to do what you intended. For example:

z = {None, 1, 2}
z.discard(None)
print(z)

Upvotes: 0

Robᵩ
Robᵩ

Reputation: 168716

Try making a copy of the set first:

for item in list(z):
    if not item:
        z.remove(item)

Upvotes: 2

Related Questions