代码之家  ›  专栏  ›  技术社区  ›  max

python filter/max组合-检查空迭代器

  •  4
  • max  · 技术社区  · 14 年前

    (使用python 3.1)

    我知道这个问题在测试迭代器是否为空的一般问题上被问了很多次;显然,没有一个很好的解决方案(我想是有原因的——迭代器在被要求返回下一个值之前并不真正知道它是否为空)。

    不过,我有一个具体的例子,希望我能用它编写干净的、蟒蛇式的代码:

    #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)
    

    有没有更好的办法?

    编辑:对不起,这个愚蠢的符号。函数的参数实际上是一个任意的iterable,而不是一个列表。

    3 回复  |  直到 12 年前
        1
  •  4
  •   Matthew Flaschen    14 年前
    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 当序列为空时。这遵循了常见的“更容易请求宽恕”的范例。

    编辑:无例外的基于reduce的解决方案

    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)
    
        2
  •  1
  •   lunixbochs    14 年前
    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
    

    列表理解只允许不计算为布尔值false的项(筛选出0和none)

    空列表,即[]的值将为false,因此“if lst:”仅在列表包含项时触发。

        3
  •  0
  •   shahjapan    14 年前

    你也可以使用reduce表达式 return reduce(lambda a,b: a<b and a or b,x) or None