Python中的条件计数

30 投票
5 回答
46961 浏览
提问于 2025-04-15 16:10

我不太确定之前有没有人问过这个问题,但我找不到明显的答案。我想要统计一个列表中有多少个元素等于某个特定的值。问题是,这些元素不是内置类型的。

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 个回答

3

我更喜欢第二种方法,因为它只需要遍历一次列表。

如果你使用 count(),你需要先遍历一次列表来获取 b 的值,然后再遍历一次来看看有多少个值等于 1。

一个不错的方法是使用 reduce()

reduce(lambda x,y: x + (1 if y.b == 1 else 0),list,0)

文档告诉我们 reduce() 的作用是:

将一个有两个参数的函数逐步应用到可迭代对象的每个元素上,从左到右,这样就能把可迭代对象简化为一个单一的值。

所以我们定义一个 lambda 函数,它只在列表项的 b 属性等于 1 的时候,把累积的值加一。

19

在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后在程序中使用这些数据。这个过程就像是从冰箱里拿食材,然后用这些食材做饭一样。

当我们提到“数据处理”时,通常是指对数据进行整理、分析或者转换,使其变得更有用。比如说,如果你有一堆数字,你可能想要计算它们的平均值,或者找出最大的那个数字。

在编程中,我们可以使用不同的工具和方法来处理数据。比如,有些编程语言提供了内置的函数,可以帮助我们快速完成这些任务。就像厨房里有各种厨具,可以帮助我们更方便地做饭。

总之,数据处理就是把原始数据变得更有用的过程,而编程则是我们实现这个过程的工具。

print sum(1 for e in L if e.b == 1)
54
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的实现方式、可用的内存量等,都可能影响具体的性能表现。

撰写回答