44

'1'我有一个 Python 列表,我想知道在这个列表中计算项目出现次数的最快方法是什么。在我的实际情况下,该项目可能会出现数万次,这就是我想要一种快速方法的原因。

['1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '7', '7', '7', '10', '10']

哪种方法:.count或者collections.Counter可能更优化?

4

5 回答 5

77
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}
于 2012-09-17T03:03:54.947 回答
18

通过使用Counter字典以最有效的方式计算所有元素的出现以及 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
于 2015-02-11T09:52:58.803 回答
3

您可以pandas通过将 , 转换list为 apd.Series然后简单地使用.value_counts()

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)
于 2018-10-09T07:43:03.417 回答
1

结合 lambda 和 map 函数也可以完成这项工作:

list_ = ['a', 'b', 'b', 'c']
sum(map(lambda x: x=="b", list_))
:2
于 2018-01-16T03:44:57.797 回答
-1

您可以将字符串中的列表转换为以空格分隔的元素,并根据要搜索的数字/字符将其拆分。

对于大型列表将是干净和快速的..

>>>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
于 2016-12-03T18:18:18.490 回答