在Python中,您可以执行
print (0 or None or False or "" or [] or "hello" or None or "bar")
将打印
hello
你能对清单做同样的事情吗?也就是说,是否存在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()
函数同时接受一个filter函数和一个iterable,并返回一个迭代器,该迭代器是通过filter的iterable中的值。
但是,当您将筛选函数设置为None
时,它与使用bool
作为筛选函数本质上是一样的,因此只允许true的值通过。然后,next()
函数将为您提供第一个这样的值。
演示:
>>> def foo(l):
... return next(filter(None, l))
...
>>> print(foo([0, None, False, "", [], "hello", None, "bar"]))
hello
您可能希望添加l
中的最后一个值作为next()
调用的默认值,以防只有虚假值;如果没有一个值是真的,v1 or v2 or v3 or v4
至少会产生v4
,所以下面的也会产生:
def foo(l):
return next(filter(None, l), l[-1])
使用filter(None, ...)
比filter(bool, ...)
快,因为filter.__next__
实现在测试bool
之前先测试None
;这种速度差很小,几乎无法测量(在误差范围内):
>>> 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
您可以将函数reduce()
与lambda
函数中的运算符or
一起使用:
from functools import reduce, partial
foo = partial(reduce, lambda x, y: x or y)
print(foo([0, None, False, "", [], "hello", None, "bar"]))
# hello