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


一个相关但不同的问题是计算集合中每个不同元素的出现次数,将字典或列表作为直方图结果而不是单个整数。有关该问题,请参阅使用字典统计列表中的项目。


当前回答

统计列表中一项的出现次数

为了只计算一个列表项的出现次数,可以使用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)]

(或类似于集合(l)中x的字典字典((x,l.count(x))))

例子:

>>> 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类

Counter(l)

例子:

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

计数器快多少?

我查了一下柜台清点清单的速度有多快。我尝试了两种方法,使用了几个n值,计数器的速度似乎快了大约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]

其他回答

如果只需要单个项目的计数,请使用计数方法:

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

重要提示:如果您正在计算多个不同的项目,这会非常缓慢

每个计数调用都会遍历n个元素的整个列表。在循环中调用计数n次意味着总共检查n次,这可能会对性能造成灾难性影响。

如果要计数多个项目,请使用计数器,它只进行n次总检查。

import pandas as pd
test = [409.1, 479.0, 340.0, 282.4, 406.0, 300.0, 374.0, 253.3, 195.1, 269.0, 329.3, 250.7, 250.7, 345.3, 379.3, 275.0, 215.2, 300.0]

#turning the list into a temporary dataframe
test  = pd.DataFrame(test)

#using the very convenient value_counts() function
df_counts = test.value_counts()
df_counts

然后可以使用dfcounts.index和dfcounts.value来获取数据。

x = ['Jess', 'Jack', 'Mary', 'Sophia', 'Karen',
     'Addison', 'Joseph','Jack', 'Jack', 'Eric', 'Ilona', 'Jason']
the_item = input('Enter the item that you wish to find : ')
how_many_times = 0 
for occurrence in x:
     if occurrence == the_item : 
          how_many_times += 1
print('The occurrence of', the_item, 'in', x,'is',how_many_times) 

创建了一个名字列表,其中重复了“Jack”这个名字。为了检查它的发生情况,我在名为x的列表中运行了一个for循环。每次迭代时,如果循环变量的值与从用户接收的值相同,并存储在变量the_item中,那么变量how_many_times将递增1。在获得某种价值之后。。。我们打印how_many_times,它存储单词“jack”出现的值

# Python >= 2.6 (defaultdict) && < 2.7 (Counter, OrderedDict)
from collections import defaultdict
def count_unsorted_list_items(items):
    """
    :param items: iterable of hashable items to count
    :type items: iterable

    :returns: dict of counts like Py2.7 Counter
    :rtype: dict
    """
    counts = defaultdict(int)
    for item in items:
        counts[item] += 1
    return dict(counts)


# Python >= 2.2 (generators)
def count_sorted_list_items(items):
    """
    :param items: sorted iterable of items to count
    :type items: sorted iterable

    :returns: generator of (item, count) tuples
    :rtype: generator
    """
    if not items:
        return
    elif len(items) == 1:
        yield (items[0], 1)
        return
    prev_item = items[0]
    count = 1
    for item in items[1:]:
        if prev_item == item:
            count += 1
        else:
            yield (prev_item, count)
            count = 1
            prev_item = item
    yield (item, count)
    return


import unittest
class TestListCounters(unittest.TestCase):
    def test_count_unsorted_list_items(self):
        D = (
            ([], []),
            ([2], [(2,1)]),
            ([2,2], [(2,2)]),
            ([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]),
            )
        for inp, exp_outp in D:
            counts = count_unsorted_list_items(inp) 
            print inp, exp_outp, counts
            self.assertEqual(counts, dict( exp_outp ))

        inp, exp_outp = UNSORTED_WIN = ([2,2,4,2], [(2,3), (4,1)])
        self.assertEqual(dict( exp_outp ), count_unsorted_list_items(inp) )


    def test_count_sorted_list_items(self):
        D = (
            ([], []),
            ([2], [(2,1)]),
            ([2,2], [(2,2)]),
            ([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]),
            )
        for inp, exp_outp in D:
            counts = list( count_sorted_list_items(inp) )
            print inp, exp_outp, counts
            self.assertEqual(counts, exp_outp)

        inp, exp_outp = UNSORTED_FAIL = ([2,2,4,2], [(2,3), (4,1)])
        self.assertEqual(exp_outp, list( count_sorted_list_items(inp) ))
        # ... [(2,2), (4,1), (2,1)]

如果您想一次计算所有值,可以使用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])