关于python:从列表中获取第一个非无值

Getting the first non None value from list

给定一个列表,是否有方法获取第一个非无值?如果是这样的话,那么用什么样的方法来做呢?

例如,我有:

  • a = objA.addreses.country.code
  • b = objB.country.code
  • c = None
  • d = 'CA'

在这种情况下,如果a不是,那么我想得到b。如果a和b都不是,那么我想得到d。

目前我正在做一些与(((a or b) or c) or d)类似的事情,还有别的方法吗?


您可以使用next()

1
2
3
>>> a = [None, None, None, 1, 2, 3, 4, 5]
>>> next(item for item in a if item is not None)
1

如果列表只包含none,它将抛出StopIteration异常。如果希望在这种情况下使用默认值,请执行以下操作:

1
2
3
>>> a = [None, None, None]
>>> next((item for item in a if item is not None), 'All are Nones')
All are Nones


first_true是在python 3文档中找到的itertools配方:

1
2
3
4
5
6
7
8
9
10
11
12
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)

您可以选择实施后一种配方或导入more_itertools,该库与itertools配方以及更多:

1
> pip install more_itertools

用途:

1
2
3
4
5
6
7
8
9
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'

为什么使用谓词?

"第一个非None项"与"第一个True项"不同,如[None, None, 0],其中0是第一个非None项,但不是第一个True项。谓词允许使用first_true,以确保仍然返回iterable中的任何第一个可见、非无、虚假项(例如0False,而不是默认项。

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


根据以下内容进行调整(如果需要,您可以将其线性化):

1
2
3
values = (a, b, c, d)
not_None = (el for el in values if el is not None)
value = next(not_None, None)

它取第一个非None值,或者返回None


我认为这是处理一组小值(也适用于列表理解)时最简单的方法:

1
firstVal = a or b or c or d

将始终返回第一个非"无"值