我有一个Python列表,想要知道最快的方法来计算在这个列表中项'1'
出现的次数。在我的实际情况中,这个项可能会出现成千上万次,因此我需要一种快速的方法。
['1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '7', '7', '7', '10', '10']
哪种方法更优化: .count
还是 collections.Counter
?
a = ['1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '7', '7', '7', '10', '10']
print a.count("1")
这可能在C语言层面得到了很好的优化。
编辑:我随机生成了一个大型列表。
In [8]: len(a)
Out[8]: 6339347
In [9]: %timeit a.count("1")
10 loops, best of 3: 86.4 ms per loop
编辑编辑:这可以使用collections.Counter完成。
a = Counter(your_list)
print a['1']
使用我上一个计时示例中的相同列表
In [17]: %timeit Counter(a)['1']
1 loops, best of 3: 1.52 s per loop
我的计时方法很简单,并且取决于许多不同的因素,但它可以为您提供有关性能的良好线索。
以下是一些分析结果
In [24]: profile.run("a.count('1')")
3 function calls in 0.091 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.091 0.091 <string>:1(<module>)
1 0.091 0.091 0.091 0.091 {method 'count' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Prof
iler' objects}
In [25]: profile.run("b = Counter(a); b['1']")
6339356 function calls in 2.143 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.143 2.143 <string>:1(<module>)
2 0.000 0.000 0.000 0.000 _weakrefset.py:68(__contains__)
1 0.000 0.000 0.000 0.000 abc.py:128(__instancecheck__)
1 0.000 0.000 2.143 2.143 collections.py:407(__init__)
1 1.788 1.788 2.143 2.143 collections.py:470(update)
1 0.000 0.000 0.000 0.000 {getattr}
1 0.000 0.000 0.000 0.000 {isinstance}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Prof
iler' objects}
6339347 0.356 0.000 0.356 0.000 {method 'get' of 'dict' objects}
count
比创建一个 Counter
快大约 20 倍,但是相同的 Counter
可以用于以极低的额外成本检索多个不同值的计数。 如果您需要从同一列表中计算 20 个或更多值,则使用 Counter
将比运行 20 次 .count()
更有效。 - John La RooyCounter
而不是.count
将我的时间缩短了一半。给Counter
点赞。 - shshnkrandom.randint(0,sys.maxsize)
数字的 list[long] 数据集(多达5000万个),尝试使用相同参数计数另一个 randint
,.count
比 Counter
快约10倍(仅尝试计数一次)。此外,我切换到 generators
,它们可以由 Counter
处理,但综合时间(生成列表/生成器+计数)更倾向于 list
和 .count
。这种行为在 Python3 和 Python2 中都是一致的。 - CristiFati通过使用计数器字典,在Python列表中以最高效的方式计算所有元素的出现次数以及最常见元素的出现值。
如果我们的Python列表为:
l=['1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '7', '7', '7', '10', '10']
要查找Python列表中每个项目的出现次数,请使用以下方法:
\>>from collections import Counter
\>>c=Counter(l)
\>>print c
Counter({'1': 6, '2': 4, '7': 3, '10': 2})
查找Python列表中最常出现的/最高出现次数的项:
\>>k=c.most_common()
\>>k
[('1', 6), ('2', 4), ('7', 3), ('10', 2)]
针对最高者:
\>>k[0][1]
6
只需使用k[0][0]即可获取该项。
\>>k[0][0]
'1'
要查找列表中第n个最高项及其出现次数,请使用以下方法:
**当n=2时**
\>>print k[n-1][0] # For item
2
\>>print k[n-1][1] # For value
4
import pandas as pd
a = ['1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '7', '7', '7', '10', '10']
a_cnts = pd.Series(a).value_counts().to_dict()
Input >> a_cnts["1"], a_cnts["10"]
Output >> (6, 2)
使用lambda和map函数的组合也可以完成任务:
list_ = ['a', 'b', 'b', 'c']
sum(map(lambda x: x=="b", list_))
:2
您可以将列表转换为由空格分隔的元素字符串,并根据要搜索的数字/字符进行拆分。
对于大型列表,这种方法会更加清晰快速。
>>>L = [2,1,1,2,1,3]
>>>strL = " ".join(str(x) for x in L)
>>>strL
2 1 1 2 1 3
>>>count=len(strL.split(" 1"))-1
>>>count
3
count
还是collections.Counter
,这就是为什么我问的原因。 - prrao.count
。 - Jakob Bowyercount
对于大型列表运行良好。 - prrao