Python filter / max combo - 检查空迭代器

时间:2010-10-15 06:28:04

标签: python filter iterator python-3.x iterable

(使用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)

有没有更好的方法呢?

编辑:抱歉这个愚蠢的符号。函数的参数确实是一个任意的迭代,而不是一个列表。

5 个答案:

答案 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")