检查iterable的所有值是不是都为零

Posted

技术标签:

【中文标题】检查iterable的所有值是不是都为零【英文标题】:Check if all values of iterable are zero检查iterable的所有值是否都为零 【发布时间】:2011-04-01 08:32:48 【问题描述】:

是否有一种简洁/内置的好方法来查看可迭代对象中的所有值是否都为零?现在我正在使用all() 和一些列表理解,但是(对我来说)似乎应该有一种更具表现力的方法。我认为这在某种程度上相当于 C 中的 memcmp()

values = (0, 0, 0, 0, 0)
# Test if all items in values tuple are zero
if all([ v == 0 for v in values ]) :
    print 'indeed they are'

我希望内置函数可以执行以下操作:

def allcmp(iter, value) :
    for item in iter :
        if item != value :
            return False
    return True

python中是否存在该功能而我只是盲目,还是应该坚持使用我的原始版本?

更新

我并不是说allcmp() 是解决方案。这是我认为可能更有意义的一个例子。这不是我建议新的 Python 内置插件的地方。

在我看来,all() 没有那么有意义。它没有表达“所有”正在检查的内容。您可以假设all() 采用可迭代对象,但它没有表达函数正在寻找什么(bools 的可迭代对象,用于测试所有这些对象的True)。我要的是一些函数,例如我的allcmp(),它接受两个参数:一个可迭代的和一个比较值。我在问是否有一个内置函数可以做类似于我编造的allcmp()

由于我的 C 背景和memcmp(),我调用了我的allcmp()我的函数名称无关紧要

【问题讨论】:

更多表现力?!?! all([ v == 0 for v in values ]) 真的非常非常好、清晰、明确和富有表现力。还能好多少? 嗯,也许我应该说的更有意义。这可能是因为我对 Python 还有些陌生,但对我来说,这行代码需要一点时间来破译。但是,if itercmp(values, 0) 似乎更有意义,因为我很快就知道我正在将所有值与 0 进行比较。不过可能只是我的 C 背景在这样做...... @mjschultz:“...我将所有值与 0 进行比较”——你怎么知道“全部”? “iter”并不意味着“全部”。比较有什么目的?检查是否有零?检查是否全为零?数零? @mjschultz:itercmp(values, 0)all([ v == 0 for v in values ]) 更“有意义”。什么?这怎么可能?请更新您的问题,并解释itercmp 如何比all() 更具表现力,而0v == 0 更具表现力。我想你不是在开玩笑,所以请更新这个问题,并解释这是如何改进的。 "all() ... 没有表达“所有”的意思?看不到你想要表达的意思。您是否希望将all 拼写为“takes_an_iterable_of_bools_and_tests_all_of_them_for_True”?这是你要求的吗? 【参考方案1】:

在这种情况下使用生成器而不是列表:

all(v == 0 for v in values)

编辑:

all 是标准的 Python 内置。如果你想成为高效的 Python 程序员,你应该知道其中的一半以上(http://docs.python.org/library/functions.html)。争论 alltrueall 更好的名字就像争论 C while 应该被称为 whiletrue。是主观的,但我认为大多数人更喜欢内置插件的较短名称。这是因为无论如何您都应该知道它们在做什么,而且您必须大量输入它们。

使用生成器比使用 numpy 更好,因为生成器具有更优雅的语法。 numpy 可能更快,但您只会在极少数情况下受益(如所示的生成器速度很快,只有当此代码成为您程序中的瓶颈时,您才会受益)。

您可能无法期待 Python 提供更多描述性内容。

附言。如果您以 memcpm 样式执行此操作,以下是代码(我更喜欢所有版本,但也许您会喜欢这个):

list(l) == [0] * len(l)

【讨论】:

有趣,我不知道生成器,谢谢你的花絮。 它似乎也相当直接地表达了你的意图。 字节字符串/字节数组有更快的方法吗?【参考方案2】:

我更喜欢使用否定:

all(not v for v in values)

【讨论】:

【参考方案3】:

any() 函数可能是实现这一目标的最简单的方法。如果迭代为空,例如所有元素都为零,它将返回 False。

values = (0, 0, 0, 0, 0)
print (any(values)) # return False

【讨论】:

建议使用 any() 而不是 all() 考虑到(最坏情况)时间缩放迭代 - 很好的答案。【参考方案4】:

内置的set 被赋予一个可迭代对象并返回一个唯一值的集合(集合)。

所以这里可以用作:

set(it) == 0
假设it 是可迭代的 0 是一个只包含零的集合

文档中有关 python set-types-set-frozenset here 的更多信息。

【讨论】:

很好地使用内置数据类型,但请记住,这会丢失索引 - 如果这很重要的话。【参考方案5】:

如果您知道可迭代对象只包含整数,那么您可以这样做:

if not any(values):
    # etc...

【讨论】:

这更短,但我认为它隐藏了它所做的更多背后的含义,因为它取决于值为== 0 -1 当您对代码进行大量注释以使非智者能够理解时,您不妨编写 'all(v == 0 for v in values)` 这是不言自明和未来证明的(当您决定它应该是零以外的某个整数时)。 代码实践主观性,if not any 是正确的英文,因为它是可读的代码。此外,在物理等某些应用程序中,0 客观上被称为“静止”或“关闭”,那么这段代码就像可读一样可维护。【参考方案6】:

如果 values 是一个 numpy 数组,你可以写

import numpy as np
values = np.array((0, 0, 0, 0, 0))
all(values == 0)

【讨论】:

那条all 正是我想要的那样富有表现力和意义。我只是希望它不依赖于 numpy。 :(

以上是关于检查iterable的所有值是不是都为零的主要内容,如果未能解决你的问题,请参考以下文章

Ikbal 有两个长度为 N 的数组 a 和 b,最初所有值都为零。

为啥 QueryVertices 中的所有坐标都为零?

检查字节数组是不是全为零的最快方法

检查字符数组是不是为零的快速方法[重复]

Vue/JS - 检查两个对象的所有值是不是为空

如果数组中的所有值都为真(字符串)并且其中一个值为假(字符串),则如何返回布尔值 true 停止使用 Javascript 进行检查