Python中的条件计数
我不太确定之前有没有人问过这个问题,但我找不到明显的答案。我想要统计一个列表中有多少个元素等于某个特定的值。问题是,这些元素不是内置类型的。
class A:
def __init__(self, a, b):
self.a = a
self.b = b
stuff = []
for i in range(1,10):
stuff.append(A(i/2, i%2))
现在我想统计列表中字段 b = 1 的元素数量。我想出了两种解决方案:
print [e.b for e in stuff].count(1)
还有
print len([e for e in stuff if e.b == 1])
哪种方法更好呢?有没有更好的选择?似乎 count() 方法不接受键(至少在 Python 2.5.1 版本中是这样)。
非常感谢!
5 个回答
我更喜欢第二种方法,因为它只需要遍历一次列表。
如果你使用 count()
,你需要先遍历一次列表来获取 b
的值,然后再遍历一次来看看有多少个值等于 1。
一个不错的方法是使用 reduce()
:
reduce(lambda x,y: x + (1 if y.b == 1 else 0),list,0)
文档告诉我们 reduce()
的作用是:
将一个有两个参数的函数逐步应用到可迭代对象的每个元素上,从左到右,这样就能把可迭代对象简化为一个单一的值。
所以我们定义一个 lambda
函数,它只在列表项的 b
属性等于 1 的时候,把累积的值加一。
在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后在程序中使用这些数据。这个过程就像是从冰箱里拿食材,然后用这些食材做饭一样。
当我们提到“数据处理”时,通常是指对数据进行整理、分析或者转换,使其变得更有用。比如说,如果你有一堆数字,你可能想要计算它们的平均值,或者找出最大的那个数字。
在编程中,我们可以使用不同的工具和方法来处理数据。比如,有些编程语言提供了内置的函数,可以帮助我们快速完成这些任务。就像厨房里有各种厨具,可以帮助我们更方便地做饭。
总之,数据处理就是把原始数据变得更有用的过程,而编程则是我们实现这个过程的工具。
print sum(1 for e in L if e.b == 1)
sum(x.b == 1 for x in L)
布尔值(比如通过比较得出的结果,比如 x.b == 1
)其实也是一种 int
(整数),它的值是 0
代表 False
(假),1
代表 True
(真),所以像加法这样的数学运算是完全可以用的。
这是最简单的代码,但可能不是最快的(只有 timeit
能告诉你确切的速度;-)。考虑一下(为了适应命令行,这里简化了,但其实是等价的):
$ py26 -mtimeit -s'L=[1,2,1,3,1]*100' 'len([x for x in L if x==1])'
10000 loops, best of 3: 56.6 usec per loop
$ py26 -mtimeit -s'L=[1,2,1,3,1]*100' 'sum(x==1 for x in L)'
10000 loops, best of 3: 87.7 usec per loop
所以,在这个例子中,生成一个额外的临时列表并检查它的长度这种“浪费内存”的方法,实际上比我通常喜欢的简单、短小、节省内存的方法要快得多。当然,列表值的不同组合、Python的实现方式、可用的内存量等,都可能影响具体的性能表现。