如何计算可迭代对象中的非空元素数量?

发布于 2024-09-13 06:59:41 字数 102 浏览 10 评论 0原文

我正在为以下代码片段寻找更好/更 Pythonic 的解决方案

count = sum(1 for e in iterable if e)

I'm looking for a better/more Pythonic solution for the following snippet

count = sum(1 for e in iterable if e)

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

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

发布评论

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

评论(9

夜唯美灬不弃 2024-09-20 06:59:41
len(list(filter(None, iterable)))

使用 None 作为 filter 的谓词只是表示使用项目的真实性。 (也许更清楚的是len(list(filter(bool, iterable)))

len(list(filter(None, iterable)))

Using None as the predicate for filter just says to use the truthiness of the items. (maybe clearer would be len(list(filter(bool, iterable))))

記柔刀 2024-09-20 06:59:41

老实说,我想不出比你所拥有的更好的方法了。

好吧,我想人们可能会争论“更好”,但我认为你不太可能找到更短、更简单、更清晰的东西。

Honestly, I can't think of a better way to do it than what you've got.

Well, I guess people could argue about "better," but I think you're unlikely to find anything shorter, simpler, and clearer.

嘿嘿嘿 2024-09-20 06:59:41
sum(not not e for e in iterable)
sum(not not e for e in iterable)
雨夜星沙 2024-09-20 06:59:41

大多数Pythonic是编写一个小的辅助函数并将其放入您值得信赖的“实用程序”模块(或适当包的子模块,当您有足够的时候;-):

import itertools as it

def count(iterable):
  """Return number of items in iterable."""
  return sum(1 for _ in iterable)

def count_conditional(iterable, predicate=None):
  """Return number of items in iterable that satisfy the predicate."""
  return count(it.ifilter(predicate, iterable))

您选择如何实现这些实用程序的确切方式是不太重要(您可以随时选择在 Cython 中重新编码其中一些,例如,如果使用实用程序对应用程序进行一些分析表明它很有用):关键是将它们作为您自己有用的实用程序函数库, 喜欢的名称和调用模式,使你最重要的应用程序级别代码比你塞满内联扭曲的代码更清晰、更易读、更简洁!-)

Most Pythonic is to write a small auxiliary function and put it in your trusty "utilities" module (or submodule of appropriate package, when you have enough;-):

import itertools as it

def count(iterable):
  """Return number of items in iterable."""
  return sum(1 for _ in iterable)

def count_conditional(iterable, predicate=None):
  """Return number of items in iterable that satisfy the predicate."""
  return count(it.ifilter(predicate, iterable))

Exactly how you choose to implement these utilities is less important (you could choose at any time to recode some of them in Cython, for example, if some profiling on an application using the utilities shows it's useful): the key thing is having them as your own useful library of utility functions, with names and calling patterns you like, to make your all-important application level code clearer, more readable, and more concise that if you stuffed it full of inlined contortions!-)

勿挽旧人 2024-09-20 06:59:41

正如评论中所述,标题与问题有些不一致。如果我们坚持标题,即计算非空元素,那么OP的解决方案可以修改为:

count = sum(1 for e in iterable if e is not None)

As stated in the comments, the title is somewhat dissonant with the question. If we would insist on the title, i.e. counting non-null elements, the OP's solution could be modified to:

count = sum(1 for e in iterable if e is not None)
谁把谁当真 2024-09-20 06:59:41

这不是最快的,但对于代码高尔夫来说可能很方便

sum(map(bool, iterable))

This isn't the fastest, but maybe handy for code-golf

sum(map(bool, iterable))
我是有多爱你 2024-09-20 06:59:41

最Pythonic的方法可能是编写不需要计数函数的代码。

通常最快的方法是编写您最擅长的函数风格,并继续完善您的风格。

编写一次常读代码。

顺便说一句,您的代码不符合您的标题所述!考虑到浮点数的舍入误差,计算非 0 个元素并不简单,即 False 为 0。

如果列表中没有浮点值,则可以这样做:

def nonzero(seq):
  return (item for item in seq if item!=0) 

seq = [None,'', 0, 'a', 3,[0], False] 
print seq,'has',len(list(nonzero(seq))),'non-zeroes' 

print 'Filter result',len(filter(None, seq))

"""Output:
[None, '', 0, 'a', 3, [0], False] has 5 non-zeroes
Filter result 3
"""

Propably the most Pythonic way is to write code that does not need count function.

Usually fastest is to write the style of functions that you are best with and continue to refine your style.

Write Once Read Often code.

By the way your code does not do what your title says! To count not 0 elements is not simple considering rounding errors in floating numbers, that False is 0..

If you have not floating point values in list, this could do it:

def nonzero(seq):
  return (item for item in seq if item!=0) 

seq = [None,'', 0, 'a', 3,[0], False] 
print seq,'has',len(list(nonzero(seq))),'non-zeroes' 

print 'Filter result',len(filter(None, seq))

"""Output:
[None, '', 0, 'a', 3, [0], False] has 5 non-zeroes
Filter result 3
"""
静谧 2024-09-20 06:59:41

如果您只是想查看可迭代是否不为空,那么这可能会有所帮助:

def is_iterable_empty(it):
    try:
        iter(it).next()
    except StopIteration:
        return True
    else:
        return False

其他答案将需要 O(N) 时间才能完成(有些需要 O(N) 内存;好眼力,约翰!)。该函数需要 O(1) 时间。如果您确实需要长度,那么其他答案会对您有更多帮助。

If you're just trying to see whether the iterable is not empty, then this would probably help:

def is_iterable_empty(it):
    try:
        iter(it).next()
    except StopIteration:
        return True
    else:
        return False

The other answers will take O(N) time to complete (and some take O(N) memory; good eye, John!). This function takes O(1) time. If you really need the length, then the other answers will help you more.

累赘 2024-09-20 06:59:41

这是一个具有 O(n) 运行时间和 O(1) 额外内存的解决方案:

count = reduce(lambda x,y:x+y, imap(lambda v: v>0, iterable))

希望有帮助!

Here is a solution with O(n) runtime and O(1) additional memory:

count = reduce(lambda x,y:x+y, imap(lambda v: v>0, iterable))

Hope that helps!

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