在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
不打印。
在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, ...))
ornext(filter(bool, ...))
从列表中找到第一个真值:
def foo(l):
return next(filter(None, l))
该filter()
函数同时接受一个过滤器函数和一个迭代器,并返回一个迭代器,该迭代器来自通过过滤器的迭代器中的值。
但是,当您将 filter 函数设置为 时None
,它与使用 filter 函数本质上是一样的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__
None
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
您可以将函数reduce()
与函数中的运算符or
一起使用lambda
:
from functools import reduce, partial
foo = partial(reduce, lambda x, y: x or y)
print(foo([0, None, False, "", [], "hello", None, "bar"]))
# hello