Getting the first non None value from list

后端 未结 5 1615
盖世英雄少女心
盖世英雄少女心 2021-01-31 13:25

Given a list, is there a way to get the first non-None value? And, if so, what would be the pythonic way to do so?

For example, I have:

  • a = objA.addr
5条回答
  •  隐瞒了意图╮
    2021-01-31 14:06

    first_true is an itertools recipe found in the Python 3 docs:

    def first_true(iterable, default=False, pred=None):
        """Returns the first true value in the iterable.
    
        If no true value is found, returns *default*
    
        If *pred* is not None, returns the first item
        for which pred(item) is true.
    
        """
        # first_true([a,b,c], x) --> a or b or c or x
        # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
        return next(filter(pred, iterable), default)
    

    One may choose to implement the latter recipe or import more_itertools, a library that ships with itertools recipes and more:

    > pip install more_itertools
    

    Use:

    import more_itertools as mit
    
    a = [None, None, None, 1, 2, 3, 4, 5]
    mit.first_true(a, pred=lambda x: x is not None)
    # 1
    
    a = [None, None, None]
    mit.first_true(a, default="All are None", pred=lambda x: x is not None)
    # 'All are None'
    

    Why use the predicate?

    "First non-None" item is not the same as "first True" item, e.g. [None, None, 0] where 0 is the first non-None, but it is not the first True item. The predicate allows first_true to be useable, ensuring any first seen, non-None, falsey item in the iterable is still returned (e.g. 0, False) instead of the default.

    a = [None, None, None, False]
    mit.first_true(a, default="All are None", pred=lambda x: x is not None)
    # 'False'
    

提交回复
热议问题