Python中的条件计数

Python中的条件计数,python,arrays,list,count,Python,Arrays,List,Count,我不确定以前有人问过这个问题,但我找不到一个明显的答案。我试图计算列表中等于某个值的元素数。问题是这些元素不是内置类型。所以如果我有 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 [

我不确定以前有人问过这个问题,但我找不到一个明显的答案。我试图计算列表中等于某个值的元素数。问题是这些元素不是内置类型。所以如果我有

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)

哪种方法最好?有更好的选择吗?count()方法似乎不接受键(至少在Python版本2.5.1中是这样)


非常感谢!

我更喜欢第二个,因为它只在列表上循环一次

print sum(1 for e in L if e.b == 1)
如果使用
count()
则在列表上循环一次以获取
b
值,然后再次循环以查看其中有多少值等于1

使用
reduce()

告诉我们
reduce()
将:

将两个参数的函数从左到右累加地应用于iterable的项,以便将iterable减少为单个值

因此,我们定义了一个
lambda
,它仅当列表项的
b
属性为1时,才将累积值加一

sum(x.b == 1 for x in L)
布尔值(由比较产生,例如
x.b==1
)也是
int
,对于
False
,其值为
0
,对于
True
,其值为
1
,因此像求和这样的算术运算效果很好

这是最简单的代码,但也许不是最快的代码(只有<代码> TimeTime/Copy>可以告诉你;-)(考虑简化的情况,以适应命令行,但等效):


因此,在这种情况下,生成额外临时列表并检查其长度的“内存浪费”方法实际上比我倾向于选择的更简单、更短、节省内存的方法要快得多当然,在这种加速等情况下,可能会影响准确的性能。

要隐藏
减少
详细信息,可以定义
计数
函数:

def count(condition, stuff):
    return reduce(lambda s, x: \
                  s + (1 if condition(x) else 0), stuff, 0)
然后,您可以通过提供计数条件来使用它:

n = count(lambda i: i.b, stuff)
给定输入

name = ['ball', 'jeans', 'ball', 'ball', 'ball', 'jeans']
price = [1, 4, 1, 1, 1, 4]
weight = [2, 2, 2, 3, 2, 2]
首先创建一个
defaultdict
来记录事件

从集合导入defaultdict
出现次数=defaultdict(int)
增加计数

邮政编码中的n、p、w(名称、价格、重量): 出现次数[(n,p,w)]+=1
最后计算出现多次的值(
True
将产生1)


也许值得解释一下它是如何工作的。并不是每个人都能清楚地看到你可以列出一个布尔值。还有,为什么这是一个比:len(如果e.b==1,则列表中的e代表e))更好的方法,它不必对元素进行汇总?@nicolaum和@Dave,我已经添加了详细的解释和计时——实际上显示了“无用的列表”方法要比简单的方法快(至少在一个示例中是这样)。最简单的方法并不总是最快的:有时如果你有空闲的、未使用的内存,“投资”这可以为您节省一些时间。@Dave,我是最初在CPython解释器中编写
sum
代码的人,我向您保证,它从来没有接近
reduce
(不确定您是从哪里得到这个主意的)。虽然这是所有示例中非常聪明和最短的代码,但我发现它是最不具python风格和明显的。
len([x代表L中的x,如果是cond])
是冗长的,并且包含一些冗余,但它的含义很明显。很好的一个,我认为这是Alex Martelli答案的更可读版本,求和1比知道真可以被视为1更明显。它本身也有一个共同的模式:
sum(len(n)代表L中的n,如果n.b==1)
例如。@TendayiMawushe:summing
1
而不是boolean值也比boolean值快约30%,至少使用Python 2.7(请参阅我对Alex答案的评论)。将列表命名为“列表”不是一个好主意。我完全同意,并更改了列表的名称。我最喜欢这种方法。不明白为什么它没有获得任何追加投票。@phunehehe:我想它没有获得追加投票,因为它是这里提出的最慢、最冗长的备选方案。有趣的是,我不记得了。也许这是answ呃符合我正在做的事情(我也不记得了):D
def count(condition, stuff):
    return reduce(lambda s, x: \
                  s + (1 if condition(x) else 0), stuff, 0)
n = count(lambda i: i.b, stuff)
name = ['ball', 'jeans', 'ball', 'ball', 'ball', 'jeans']
price = [1, 4, 1, 1, 1, 4]
weight = [2, 2, 2, 3, 2, 2]
print(sum(cnt > 1 for cnt in occurrences.values())