Python filter / max combo - проверка пустого итератора - PullRequest
5 голосов
/ 15 октября 2010

(с использованием 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)

Есть ли лучший способ сделать это?

РЕДАКТИРОВАТЬ: извините за глупые обозначения. Параметр функции действительно является произвольной итерацией, а не списком.

Ответы [ 3 ]

5 голосов
/ 15 октября 2010
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 голос
/ 15 октября 2010
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 и ничего)

пустой список, т. Е. [] Будет иметь значение False, поэтому «if lst:» будет срабатывать только в том случае, если список содержит элементы

0 голосов
/ 15 октября 2010

Вы можете пойти и уменьшить выражение return reduce(lambda a,b: a<b and a or b,x) or None

...