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:summing1
而不是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())