检查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()
采用可迭代对象,但它没有表达函数正在寻找什么(bool
s 的可迭代对象,用于测试所有这些对象的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()
更具表现力,而0
比v == 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)。争论 alltrue
比 all
更好的名字就像争论 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,最初所有值都为零。
如果数组中的所有值都为真(字符串)并且其中一个值为假(字符串),则如何返回布尔值 true 停止使用 Javascript 进行检查