Python 过滤器/最大组合 - 检查空迭代器

发布于 2024-09-27 17:30:02 字数 505 浏览 10 评论 0 原文

(使用Python 3.1)

我知道这个问题已经被问过很多次,用于测试迭代器是否为空的一般问题;显然,对此没有简洁的解决方案(我猜是有原因的 - 迭代器在被要求返回下一个值之前并不真正知道它是否为空)。

然而,我有一个具体的例子,希望我能从中编写出干净且 Python 的代码:

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

有没有更好的方法来做到这一点?

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

(Using Python 3.1)

I know this question has been asked many times for the general question of testing if iterator is empty; obviously, there's no neat solution to that (I guess for a reason - an iterator doesn't really know if it's empty until it's asked to return its next value).

I have a specific example, however, and was hoping I can make clean and Pythonic code out of it:

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

Is there any better way to do that?

EDIT: sorry for the stupid notation. The parameter to the function is indeed an arbitrary iterable, rather than a list.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

永言不败 2024-10-04 17:30:02
t = [1,2,3]
if any(filter(lambda x: x == 10, t)):
   print("found 10")
t = [1,2,3]
if any(filter(lambda x: x == 10, t)):
   print("found 10")
隔岸观火 2024-10-04 17:30:02
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)
def f(lst):
  flt = filter(lambda x : x is not None and x != 0, lst)
  try:
    return min(flt)
  except ValueError:
    return None

min throws ValueError when the sequence is empty. This follows the common "Easier to Ask for Forgiveness" paradigm.

EDIT: A reduce-based solution without exceptions

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)
变身佩奇 2024-10-04 17:30:02
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

列表理解只允许不计算为 boolean false 的项目(过滤掉 0 和 None)

空列表,即 [] 将计算为 False,因此“if lst:”仅在列表有项目时才会触发

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

the list comprehension only allows items that don't evaluate to boolean false (which filters out 0 and None)

an empty list i.e. [] will evaluate to False, so "if lst:" will only trigger if the list has items

紫竹語嫣☆ 2024-10-04 17:30:02

如果您只想检查过滤器的返回是否为空,您可以这样做 (Python3)

len(list(filter(lambda e : e == 2, [1,2,3])))

但请注意,因此 filter 是一个生成器,如果您测试两次,第二次,您将收到不同的结果:

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])
长度(列表(f))
len(list(f))

>>> 1

>>>> 0

If you just want to check if the return of filter is empty, you might do (Python3)

len(list(filter(lambda e : e == 2, [1,2,3])))

But notice, hence filter is a generator if you this test twice, second time, you will receive a diferent result:

len(list(filter(lambda e : e == 2, [1,2,3])))
len(list(filter(lambda e : e == 2, [1,2,3])))

>>> 1

>>> 1

But:

f = filter(lambda e : e == 2, [1,2,3])
len(list(f))
len(list(f))

>>> 1

>>> 0

傻比既视感 2024-10-04 17:30:02

你也可以使用reduce表达式return reduce(lambda a,b: a

you can go for reduce expression too return reduce(lambda a,b: a<b and a or b,x) or None

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文