(使用Python 3.1)
我知道这个问题多次被问到测试迭代器是否为空的一般问题;很明显,没有那个简洁的解决方案(我猜有一个原因 - 迭代器在它被要求返回其下一个值之前并不知道它是否为空。)
然而,我有一个具体的例子,希望我能用它制作干净的Pythonic代码:
#lst is an arbitrary iterable
#f must return the smallest non-zero element, or return None if empty
def f(lst):
flt = filter(lambda x : x is not None and x != 0, lst)
if # somehow check that flt is empty
return None
return min(flt)
有没有更好的方法呢?
编辑:抱歉这个愚蠢的符号。函数的参数确实是一个任意的迭代,而不是一个列表。答案 0 :(得分:4)
def f(lst):
flt = filter(lambda x : x is not None and x != 0, lst)
try:
return min(flt)
except ValueError:
return None
当序列为空时, min
抛出ValueError
。这遵循了常见的“更容易请求宽恕”的范例。
编辑:基于减少的解决方案,无异常
from functools import reduce
def f(lst):
flt = filter(lambda x : x is not None and x != 0, lst)
m = next(flt, None)
if m is None:
return None
return reduce(min, flt, m)
答案 1 :(得分:1)
def f(lst):
# if you want the exact same filtering as the original, you could use
# lst = [item for item in lst if (item is not None and item != 0)]
lst = [item for item in lst if item]
if lst: return min(lst)
else: return None
list comprehension只允许不评估的项目为boolean false(过滤掉0和None)
一个空列表,即[]将评估为False,因此“if lst:”只会在列表中有项目时触发
答案 2 :(得分:1)
如果您只想检查过滤器的返回是否为空,则可以这样做(Python3)
len(list(filter(lambda e : e == 2, [1,2,3])))
但是请注意,因此,如果您两次进行此测试两次,过滤器就是一个生成器,您将收到不同的结果:
len(list(filter(lambda e : e == 2, [1,2,3])))
len(list(filter(lambda e : e == 2, [1,2,3])))
>>> 1
>>> 1
但是:
f = filter(lambda e : e == 2, [1,2,3])
len(list(f))
len(list(f))
>>> 1
>>> 0
答案 3 :(得分:0)
您也可以使用缩小表达式return reduce(lambda a,b: a<b and a or b,x) or None
答案 4 :(得分:0)
t = [1,2,3]
if any(filter(lambda x: x == 10, t)):
print("found 10")