Loïc Faure-Lacroix Loïc Faure-Lacroix - 3 months ago 10x
Python Question

Pop a value from a set using a condition

I have a set of objects, and I'd like to remove values of the set using a lambda expression.

I'd do this like that:

def pop(container, cond):
value = None
removed = False

for x in container:
if cond(x):
value = x
removed = True

if not removed:
raise Exception('No value to pop')

return value

An example usecase is:

compare_object = {"price": 100, "quantity": 1, "product_id": 2}
objs = set([....])

def comparison(obj):
def wrap(obj2):
return (
obj2['price'] == obj['price'] and
obj2['quantity'] == obj['quantity'] and
obj2['product_id'] == obj['product_id']

similar_obj = pop(objs, comparison(compare_object))

This way, we can get a similar object from a set and consequently the set will be reduced after a call to the method.

I'd like to know if there is a simpler way to do this with an actual data structure already available in python.


Instead of your complicated for loop, you could create a filter from that condition (or itertools.ifilter for Python 2) and remove the next element from that filter.

def pop(container, cond):
        value = next(filter(cond, container))
        return value
    except StopIteration:
        raise Exception("No Value to pop")


>>> lst = [1,2,3,4,5]
>>> cond = lambda x: x % 2 == 0
>>> pop(lst, cond)
>>> pop(lst, cond)
>>> pop(lst, cond)
Exception: No Value to pop
>>> lst
[1, 3, 5]

Or you could just simplify your function by immediately returning the found value:

def pop(container, cond):
    for x in container:
        if cond(x):
            return x
    raise Exception('No value to pop')