题 如何计算列表项的出现次数?


给定一个项目,如何在Python的列表中计算它的出现次数?


1087
2018-04-08 13:30


起源




答案:


如果您只想要一个项目的计数,请使用 count 方法:

>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3

 如果要计算多个项目,请使用此项。调用 count 在循环中需要在列表上单独传递每个 count 呼叫,这对性能来说可能是灾难性的。如果您想要计算所有项目,甚至只计算多个项目,请使用 Counter,正如其他答案中所解释的那样。


1431
2018-04-08 13:31



mylist = [1,7,7,7,3,9,9,9,7,9,10,0] print sorted(set([i for i in mylist if mylist.count(i)>2])) - cpp-coder


如果您使用的是Python 2.7或3,并且您希望每个元素出现次数:

>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> Counter(z)
Counter({'blue': 3, 'red': 2, 'yellow': 1})

1363
2018-04-29 07:44



我发现当使用它时(谈论数百万字符串)它因为调用它而非常慢 isinstance。因此,如果您确定要使用的数据,那么编写没有类型和实例检查的自定义函数可能会更好。 - Bram Vanroy


计算列表中一个项目的出现次数

用于计算您可以使用的仅一个列表项的出现次数 count()

>>> l = ["a","b","b"]
>>> l.count("a")
1
>>> l.count("b")
2

计算出现的次数 所有 列表中的项目也称为“统计”列表,或创建计数器。

使用count()计算所有项目

计算项目的出现次数 l 一个人可以简单地使用列表理解和 count() 方法

[[x,l.count(x)] for x in set(l)]

(或类似于字典 dict((x,l.count(x)) for x in set(l))

例:

>>> l = ["a","b","b"]
>>> [[x,l.count(x)] for x in set(l)]
[['a', 1], ['b', 2]]
>>> dict((x,l.count(x)) for x in set(l))
{'a': 1, 'b': 2}

使用Counter()计算所有项目

或者,速度更快 Counter 来自的班级 collections 图书馆

Counter(l)

例:

>>> l = ["a","b","b"]
>>> from collections import Counter
>>> Counter(l)
Counter({'b': 2, 'a': 1})

Counter多快了?

我检查了多快 Counter 用于计算清单。我用两个值来尝试两种方法 n 而且似乎 Counter 通过大约2的常数因子更快。

这是我用过的脚本:

from __future__ import print_function
import timeit

t1=timeit.Timer('Counter(l)', \
                'import random;import string;from collections import Counter;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]'
                )

t2=timeit.Timer('[[x,l.count(x)] for x in set(l)]',
                'import random;import string;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]'
                )

print("Counter(): ", t1.repeat(repeat=3,number=10000))
print("count():   ", t2.repeat(repeat=3,number=10000)

并输出:

Counter():  [0.46062711701961234, 0.4022796869976446, 0.3974247490405105]
count():    [7.779430688009597, 7.962715800967999, 8.420845870045014]

186
2018-05-28 10:58



Counter 是 办法 更大的列表更快。列表理解方法是O(n ^ 2), Counter 应该是O(n)。 - fhucho
计数器速度不是2倍,计数器速度快了 因子 (O(n ^ 2)vs O(n))。 - Martijn Pieters♦
count() 只是说,也适用于字符串 - Jacob Schneider
我发现当使用它时(谈论数百万字符串)它因为调用它而非常慢 isinstance。因此,如果您确定要使用的数据,那么编写没有类型和实例检查的自定义函数可能会更好。 - Bram Vanroy


在字典中获取每个项目出现次数的另一种方法:

dict((i, a.count(i)) for i in a)

56
2017-10-20 22:38



这看起来像我在战斗中经常提出的构造之一,但它会经历len(a)次,这意味着二次运行时复杂性(因为每次运行再次依赖于len(a))。 - Nicolas78
dict((i,a.count(i))for set in a(a))是否更正确,更快? - hugo24
@ hugo24:有点,但在最坏的情况下它不会渐近快;它需要 n * (number of different items) 操作,不计算构建集合所需的时间。运用 collections.Counter 真的好多了 - Clément


list.count(x) 返回次数 x 出现在列表中

看到: http://docs.python.org/tutorial/datastructures.html#more-on-lists


40
2018-04-08 13:34





如果你想 一次计算所有值 你可以使用numpy数组快速地完成它 bincount 如下

import numpy as np
a = np.array([1, 2, 3, 4, 1, 4, 1])
np.bincount(a)

这使

>>> array([0, 3, 1, 1, 2])

27
2017-11-19 10:53





给定一个项目,如何在Python的列表中计算它的出现次数?

这是一个示例列表:

>>> l = list('aaaaabbbbcccdde')
>>> l
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e']

list.count

list.count 方法

>>> l.count('b')
4

这适用于任何列表。元组也有这种方法:

>>> t = tuple('aabbbffffff')
>>> t
('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f')
>>> t.count('f')
6

collections.Counter

然后就是馆藏。计数器。您可以将任何iterable转储到Counter中,而不仅仅是列表,Counter将保留元素计数的数据结构。

用法:

>>> from collections import Counter
>>> c = Counter(l)
>>> c['b']
4

计数器基于Python字典,它们的键是元素,因此键需要是可清除的。它们基本上就像允许冗余元素进入它们的集合。

进一步使用 collections.Counter

您可以使用计数器中的可迭代添加或减去:

>>> c.update(list('bbb'))
>>> c['b']
7
>>> c.subtract(list('bbb'))
>>> c['b']
4

您也可以使用计数器进行多组操作:

>>> c2 = Counter(list('aabbxyz'))
>>> c - c2                   # set difference
Counter({'a': 3, 'c': 3, 'b': 2, 'd': 2, 'e': 1})
>>> c + c2                   # addition of all elements
Counter({'a': 7, 'b': 6, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1})
>>> c | c2                   # set union
Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1})
>>> c & c2                   # set intersection
Counter({'a': 2, 'b': 2})

为什么不是熊猫?

另一个答案暗示:

为什么不用熊猫?

Pandas是一个常见的库,但它不在标准库中。将其添加为依赖项并非易事。

在列表对象本身以及标准库中有针对此用例的内置解决方案。

如果您的项目不需要pandas,那么仅仅为此功能提供它是愚蠢的。


23
2018-04-13 12:50





我已将所有建议的解决方案(以及一些新解决方案)与之进行了比较 perfplot (我的一个小项目)。

数数  项目

对于足够大的数组,事实证明

numpy.sum(numpy.array(a) == 1) 

比其他解决方案略快。

enter image description here

数数 所有 项目

如前所述

numpy.bincount(a)

是你想要的。

enter image description here


重现情节的代码:

from collections import Counter
from collections import defaultdict
import numpy
import operator
import pandas
import perfplot


def counter(a):
    return Counter(a)


def count(a):
    return dict((i, a.count(i)) for i in set(a))


def bincount(a):
    return numpy.bincount(a)


def pandas_value_counts(a):
    return pandas.Series(a).value_counts()


def occur_dict(a):
    d = {}
    for i in a:
        if i in d:
            d[i] = d[i]+1
        else:
            d[i] = 1
    return d


def count_unsorted_list_items(items):
    counts = defaultdict(int)
    for item in items:
        counts[item] += 1
    return dict(counts)


def operator_countof(a):
    return dict((i, operator.countOf(a, i)) for i in set(a))


perfplot.show(
    setup=lambda n: list(numpy.random.randint(0, 100, n)),
    n_range=[2**k for k in range(20)],
    kernels=[
        counter, count, bincount, pandas_value_counts, occur_dict,
        count_unsorted_list_items, operator_countof
        ],
    equality_check=None,
    logx=True,
    logy=True,
    )

2。

from collections import Counter
from collections import defaultdict
import numpy
import operator
import pandas
import perfplot


def counter(a):
    return Counter(a)


def count(a):
    return dict((i, a.count(i)) for i in set(a))


def bincount(a):
    return numpy.bincount(a)


def pandas_value_counts(a):
    return pandas.Series(a).value_counts()


def occur_dict(a):
    d = {}
    for i in a:
        if i in d:
            d[i] = d[i]+1
        else:
            d[i] = 1
    return d


def count_unsorted_list_items(items):
    counts = defaultdict(int)
    for item in items:
        counts[item] += 1
    return dict(counts)


def operator_countof(a):
    return dict((i, operator.countOf(a, i)) for i in set(a))


perfplot.show(
    setup=lambda n: list(numpy.random.randint(0, 100, n)),
    n_range=[2**k for k in range(20)],
    kernels=[
        counter, count, bincount, pandas_value_counts, occur_dict,
        count_unsorted_list_items, operator_countof
        ],
    equality_check=None,
    logx=True,
    logy=True,
    )

20
2017-09-13 10:32



numpy.bincount()仅适用于具有int项的列表。 - Mukarram Pasha


如果可以使用 pandas, 然后 value_counts 是救援。

>>> import pandas as pd
>>> a = [1, 2, 3, 4, 1, 4, 1]
>>> pd.Series(a).value_counts()
1    3
4    2
3    1
2    1
dtype: int64

它还会根据频率自动对结果进行排序。

如果您希望结果位于列表列表中,请执行以下操作

>>> pd.Series(a).value_counts().reset_index().values.tolist()
[[1, 3], [4, 2], [3, 1], [2, 1]]

14
2018-01-17 07:56





为什么不使用熊猫?

import pandas as pd

l = ['a', 'b', 'c', 'd', 'a', 'd', 'a']

# converting the list to a Series and counting the values
my_count = pd.Series(l).value_counts()
my_count

输出:

a    3
d    2
b    1
c    1
dtype: int64

如果您正在寻找特定元素的计数,请说 一个,尝试:

my_count['a']

输出:

3

13
2017-10-17 17:15