Get the first item from an iterable that matches a condition

前端 未结 13 2299
感情败类
感情败类 2020-11-22 04:43

I would like to get the first item from a list matching a condition. It\'s important that the resulting method not process the entire list, which could be quite large. For e

13条回答
  •  误落风尘
    2020-11-22 05:06

    As a reusable, documented and tested function

    def first(iterable, condition = lambda x: True):
        """
        Returns the first item in the `iterable` that
        satisfies the `condition`.
    
        If the condition is not given, returns the first item of
        the iterable.
    
        Raises `StopIteration` if no item satysfing the condition is found.
    
        >>> first( (1,2,3), condition=lambda x: x % 2 == 0)
        2
        >>> first(range(3, 100))
        3
        >>> first( () )
        Traceback (most recent call last):
        ...
        StopIteration
        """
    
        return next(x for x in iterable if condition(x))
    

    Version with default argument

    @zorf suggested a version of this function where you can have a predefined return value if the iterable is empty or has no items matching the condition:

    def first(iterable, default = None, condition = lambda x: True):
        """
        Returns the first item in the `iterable` that
        satisfies the `condition`.
    
        If the condition is not given, returns the first item of
        the iterable.
    
        If the `default` argument is given and the iterable is empty,
        or if it has no items matching the condition, the `default` argument
        is returned if it matches the condition.
    
        The `default` argument being None is the same as it not being given.
    
        Raises `StopIteration` if no item satisfying the condition is found
        and default is not given or doesn't satisfy the condition.
    
        >>> first( (1,2,3), condition=lambda x: x % 2 == 0)
        2
        >>> first(range(3, 100))
        3
        >>> first( () )
        Traceback (most recent call last):
        ...
        StopIteration
        >>> first([], default=1)
        1
        >>> first([], default=1, condition=lambda x: x % 2 == 0)
        Traceback (most recent call last):
        ...
        StopIteration
        >>> first([1,3,5], default=1, condition=lambda x: x % 2 == 0)
        Traceback (most recent call last):
        ...
        StopIteration
        """
    
        try:
            return next(x for x in iterable if condition(x))
        except StopIteration:
            if default is not None and condition(default):
                return default
            else:
                raise
    

提交回复
热议问题