Python 或列表

Python OR for list

在 Python 你可以做到

print (0 or None or False or "" or [] or "hello" or None or "bar")

这将打印

hello

你能对列表做同样的事情吗? IE。是否有 Python 函数 foo 以便以下内容也将打印 hello?

print (foo([0, None, False, "", [], "hello", None, "bar"]))

请注意,bar 未打印。

您可以使用 next(filter(None, ...))next(filter(bool, ...)) 从列表中找到第一个真值:

def foo(l):
    return next(filter(None, l))

filter() function 接受一个过滤器函数和一个可迭代对象,returns 一个迭代器,该迭代器是可迭代对象中通过过滤器的值的迭代器。

但是当你将过滤器函数设置为 None 时,它与使用 bool 作为过滤器函数本质上是一样的,所以只有 are true are allowed through. The next() function 给你的值第一个这样的值。

演示:

>>> def foo(l):
...     return next(filter(None, l))
...
>>> print(foo([0, None, False, "", [], "hello", None, "bar"]))
hello

可能想要添加 l 中的最后一个值作为 next() 调用的默认值,以防只有假值;如果 none 的值是真实的,v1 or v2 or v3 or v4 至少会产生 v4,所以下面的值也是如此:

def foo(l):
    return next(filter(None, l), l[-1])

使用 filter(None, ...)filter(bool, ...) 分数 因为 filter.__next__ 实现 tests for None before it tests for bool;这个速度差异非常小,几乎无法测量(在误差范围内):

>>> import timeit
>>> import random
>>> t = [random.choice([True, False]) for _ in range(10 ** 6)]
>>> for ff in ('bool', 'None'):
...     count, total = timeit.Timer(f'deque(filter({ff}, t), maxlen=0)', 'from collections import deque; from __main__ import t').autorange()
...     print(f"{ff}: {total / count * 1000:8.4f} ms")
...
bool:  98.9971 ms
None:  95.7907 ms

您可以在 lambda 函数中将函数 reduce() 与运算符 or 一起使用:

from functools import reduce, partial

foo = partial(reduce, lambda x, y: x or y)

print(foo([0, None, False, "", [], "hello", None, "bar"]))
# hello