Python OR for list



在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

相关内容

  • 没有找到相关文章

最新更新