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

wea*_*ish 1417 python list count

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

Łuk*_*asz 1730

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

>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3
Run Code Online (Sandbox Code Playgroud)

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

  • 在我的例子中,计算唯一元素的时间如下:**114.19**秒(使用“list.count()”)、**0.53**秒(使用“numpy.unique(list, return_counts = True)”)和 **0.17* * 秒与“计数器”。差异是惊人的。 (9认同)
  • `mylist = [1,7,7,7,3,9,9,9,7,9,10,0]打印排序(set([[如果mylist.count(i)> 2为i,则为mylist中的i] )` (4认同)

use*_*778 1627

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

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

  • 如果您想对结果进行排序[how-to-sort-counter-by-value-python](/sf/ask/1466545531/) --> `x = Counter({'a':5, 'b':3, 'c':7})` `x.most_common()` (5认同)
  • 我发现当大量使用它时(谈论数百万个字符串),由于它对 `isinstance` 的调用,它非常慢。因此,如果您确定要处理的数据,最好编写一个不检查类型和实例的自定义函数。 (3认同)
  • @BramVanroy:isinstance叫什么?即使有数百万个字符串,调用“ Counter”也仅涉及一个“ isinstance”调用,以检查其参数是否为映射。您很可能一直都在误判正在吃什么。 (2认同)
  • @BramVanroy:如果您要执行数百万个* update *而不是仅仅数百万个字符串,那是另一回事了。“ Counter”中的优化工作已用于计算大型可迭代对象,而不是对许多可迭代对象进行计数。使用Counter计数一百万个字符串的迭代将比使用手动实现更快。如果您想使用许多可迭代项调用`update`,则可以通过使用`itertools.chain`将它们合并为一个可迭代项来加快处理速度。 (2认同)

use*_*737 245

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

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

>>> l = ["a","b","b"]
>>> l.count("a")
1
>>> l.count("b")
2
Run Code Online (Sandbox Code Playgroud)

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

使用count()计算所有项目

要计算l一个项目的出现次数,只需使用列表推导和count()方法即可

[[x,l.count(x)] for x in set(l)]
Run Code Online (Sandbox Code Playgroud)

(或类似于字典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}
Run Code Online (Sandbox Code Playgroud)

使用Counter()计算所有项目

或者,库中的Counter类更快collections

Counter(l)
Run Code Online (Sandbox Code Playgroud)

例:

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

计数器的速度有多快?

我检查了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)
Run Code Online (Sandbox Code Playgroud)

并输出:

Counter():  [0.46062711701961234, 0.4022796869976446, 0.3974247490405105]
count():    [7.779430688009597, 7.962715800967999, 8.420845870045014]
Run Code Online (Sandbox Code Playgroud)

  • 对于更大的列表,`Counter`是*way*更快.列表理解方法是O(n ^ 2),"Counter"应该是O(n). (29认同)
  • 计数器速度不快2倍,计数器速度快*因子n*(O(n ^ 2)vs O(n)). (18认同)
  • 我发现当大量使用它时(谈论数百万个字符串),由于它对 `isinstance` 的调用,它非常慢。因此,如果您确定要处理的数据,最好编写一个不检查类型和实例的自定义函数。 (2认同)

小智 63

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

dict((i, a.count(i)) for i in a)
Run Code Online (Sandbox Code Playgroud)

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

Sil*_*rom 44

list.count(x)返回x列表中显示的次数

请参阅:http: //docs.python.org/tutorial/datastructures.html#more-on-lists


Aar*_*all 42

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

这是一个示例列表:

>>> l = list('aaaaabbbbcccdde')
>>> l
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e']
Run Code Online (Sandbox Code Playgroud)

list.count

list.count方法

>>> l.count('b')
4
Run Code Online (Sandbox Code Playgroud)

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

>>> t = tuple('aabbbffffff')
>>> t
('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f')
>>> t.count('f')
6
Run Code Online (Sandbox Code Playgroud)

collections.Counter

然后是收藏品.计数器.您可以将任何可迭代转储到计数器中,而不仅仅是列表,并且计数器将保留元素计数的数据结构.

用法:

>>> from collections import Counter
>>> c = Counter(l)
>>> c['b']
4
Run Code Online (Sandbox Code Playgroud)

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

进一步使用 collections.Counter

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

>>> c.update(list('bbb'))
>>> c['b']
7
>>> c.subtract(list('bbb'))
>>> c['b']
4
Run Code Online (Sandbox Code Playgroud)

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

>>> 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})
Run Code Online (Sandbox Code Playgroud)

为什么不是熊猫?

另一个答案暗示:

为什么不用熊猫?

Pandas是一个常见的库,但它不在标准库中.将其添加为要求并非易事.

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

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

  • 尽管“为什么不使用熊猫”是适当的,但它可能应该伴随“何时使用NumPy”,即用于大型数字数组。决定因素不仅是项目限制,NumPy的存储效率在大数据中也很明显。 (4认同)
  • 感谢您提到 Pandas/etc 是一个严重的依赖项。其中一些软件包具有负面影响。因此,为琐碎的需求添加这些资产可能会花费大量的时间和金钱。就我个人而言,我经历过 Numpy 和 SciPi 将 30 分钟添加到我们的 CI 管道中,并且花了几天时间才能正确获得包缓存。很棒的套餐,但有时会有隐藏费用。+1'd (2认同)

flo*_*onk 34

如果要一次计算所有值,可以使用numpy数组快速完成bincount,如下所示

import numpy as np
a = np.array([1, 2, 3, 4, 1, 4, 1])
np.bincount(a)
Run Code Online (Sandbox Code Playgroud)

这使

>>> array([0, 3, 1, 1, 2])
Run Code Online (Sandbox Code Playgroud)


Nic*_*mer 33

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

计算一个项目

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

numpy.sum(numpy.array(a) == 1) 
Run Code Online (Sandbox Code Playgroud)

比其他解决方案略快.

在此输入图像描述

计算所有项目

如前所述,

numpy.bincount(a)
Run Code Online (Sandbox Code Playgroud)

是你想要的.

在此输入图像描述


重现图的代码:

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,
    )
Run Code Online (Sandbox Code Playgroud)

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,
    )
Run Code Online (Sandbox Code Playgroud)

  • numpy.bincount()仅适用于具有int项的列表. (6认同)

Thi*_*vel 19

如果你可以使用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
Run Code Online (Sandbox Code Playgroud)

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

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

>>> pd.Series(a).value_counts().reset_index().values.tolist()
[[1, 3], [4, 2], [3, 1], [2, 1]]
Run Code Online (Sandbox Code Playgroud)


Sho*_*esh 14

为什么不使用熊猫?

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
Run Code Online (Sandbox Code Playgroud)

输出:

a    3
d    2
b    1
c    1
dtype: int64
Run Code Online (Sandbox Code Playgroud)

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

my_count['a']
Run Code Online (Sandbox Code Playgroud)

输出:

3
Run Code Online (Sandbox Code Playgroud)


小智 13

我今天遇到了这个问题并且在我想要检查之前推出了我自己的解决方案.这个:

dict((i,a.count(i)) for i in a)
Run Code Online (Sandbox Code Playgroud)

对于大型列表来说真的非常慢.我的解决方案

def occurDict(items):
    d = {}
    for i in items:
        if i in d:
            d[i] = d[i]+1
        else:
            d[i] = 1
return d
Run Code Online (Sandbox Code Playgroud)

实际上比Counter解决方案快一点,至少对于Python 2.7来说.

  • Python 2中的计数器有点偏慢,是的.它使用C优化代码在Python 3中进行计数,然而现在轻松地击败你的循环. (3认同)

Wes*_*ner 12

# 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)]
Run Code Online (Sandbox Code Playgroud)

  • @Wes Turner很高兴,你使用Python.想象一下Java或C中的相同内容.... (3认同)
  • @plaes:怎么样?如果用'enterprisey',你的意思是"记录"以准备Py3k注释,我同意. (2认同)

Har*_*cha 11

虽然这是一个很老的问题,但由于我没有找到一个班轮,我做了一个。

# original numbers in list
l = [1, 2, 2, 3, 3, 3, 4]

# empty dictionary to hold pair of number and its count
d = {}

# loop through all elements and store count
[ d.update( {i:d.get(i, 0)+1} ) for i in l ]

print(d)
# {1: 1, 2: 2, 3: 3, 4: 1}
Run Code Online (Sandbox Code Playgroud)

  • 不要使用列表推导式来产生副作用。请参阅:[仅使用列表推导式来产生副作用是 Pythonic 吗?](/sf/ask/402751821/ ) (3认同)

Tim*_*sen 9

所有元素的计数 itertools.groupby()

获取列表中所有元素的计数的另一种可能性是使用itertools.groupby()

具有“重复”计数

from itertools import groupby

L = ['a', 'a', 'a', 't', 'q', 'a', 'd', 'a', 'd', 'c']  # Input list

counts = [(i, len(list(c))) for i,c in groupby(L)]      # Create value-count pairs as list of tuples 
print(counts)
Run Code Online (Sandbox Code Playgroud)

退货

[('a', 3), ('t', 1), ('q', 1), ('a', 1), ('d', 1), ('a', 1), ('d', 1), ('c', 1)]
Run Code Online (Sandbox Code Playgroud)

请注意,它是如何将前三个组合在一起a作为第一组的,而其他组合a则位于列表的下方。发生这种情况是因为未对输入列表L进行排序。如果组实际上应该分开,那么有时这可能是一个好处。

具有独特的计数

如果需要唯一的组计数,只需对输入列表进行排序:

counts = [(i, len(list(c))) for i,c in groupby(sorted(L))]
print(counts)
Run Code Online (Sandbox Code Playgroud)

退货

[('a', 5), ('c', 1), ('d', 2), ('q', 1), ('t', 1)]
Run Code Online (Sandbox Code Playgroud)

注意:为了创建唯一计数,与groupby解决方案相比,许多其他答案都提供了更轻松,更易读的代码。但是这里显示它与重复计数示例相似。


eyq*_*uem 6

要计算具有共同类型的不同元素的数量:

li = ['A0','c5','A8','A2','A5','c2','A3','A9']

print sum(1 for el in li if el[0]=='A' and el[1] in '01234')
Run Code Online (Sandbox Code Playgroud)

3 而不是6


vis*_*ell 6

您还可以使用countOf内置模块的方法operator

>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
Run Code Online (Sandbox Code Playgroud)

  • `countOf`是如何实现的?它与更明显的“list.count”(受益于 C 实现)相比如何?有什么优点吗? (2认同)

And*_*dyK 6

建议使用numpy的bincount,但是它仅适用于具有非负整数的一维数组。而且,结果数组可能会造成混淆(它包含原始列表的从最小值到最大值的整数的出现,并将丢失的整数设置为0)。

使用numpy更好的方法是使用属性设置为True 的唯一函数return_counts。它返回一个元组,该元组具有唯一值的数组和每个唯一值的出现的数组。

# a = [1, 1, 0, 2, 1, 0, 3, 3]
a_uniq, counts = np.unique(a, return_counts=True)  # array([0, 1, 2, 3]), array([2, 3, 1, 2]
Run Code Online (Sandbox Code Playgroud)

然后我们可以将它们配对为

dict(zip(a_uniq, counts))  # {0: 2, 1: 3, 2: 1, 3: 2}
Run Code Online (Sandbox Code Playgroud)

它还可以与其他数据类型和“ 2d列表”一起使用,例如

>>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']]
>>> dict(zip(*np.unique(a, return_counts=True)))
{'a': 3, 'b': 3, 'c': 2}
Run Code Online (Sandbox Code Playgroud)


Aka*_*ain 6

以下是三种解决方案:

最快的是使用for循环并将其存储在Dict中。

import time
from collections import Counter


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


z = [1,1,1,1,2,2,2,2,3,3,4,5,5,234,23,3,12,3,123,12,31,23,13,2,4,23,42,42,34,234,23,42,34,23,423,42,34,23,423,4,234,23,42,34,23,4,23,423,4,23,4]


#Solution 1 - Faster
st = time.monotonic()
for i in range(1000000):
    b = countElement(z)
et = time.monotonic()
print(b)
print('Simple for loop and storing it in dict - Duration: {}'.format(et - st))

#Solution 2 - Fast
st = time.monotonic()
for i in range(1000000):
    a = Counter(z)
et = time.monotonic()
print (a)
print('Using collections.Counter - Duration: {}'.format(et - st))

#Solution 3 - Slow
st = time.monotonic()
for i in range(1000000):
    g = dict([(i, z.count(i)) for i in set(z)])
et = time.monotonic()
print(g)
print('Using list comprehension - Duration: {}'.format(et - st))
Run Code Online (Sandbox Code Playgroud)

结果

#Solution 1 - Faster
Run Code Online (Sandbox Code Playgroud)
{1: 4, 2: 5, 3: 4, 4: 6, 5: 2, 234: 3, 23: 10, 12: 2, 123: 1, 31: 1, 13: 1, 42: 5, 34: 4, 423: 3}
Simple for loop and storing it in dict - Duration: 12.032000000000153
Run Code Online (Sandbox Code Playgroud)
#Solution 2 - Fast
Run Code Online (Sandbox Code Playgroud)
Counter({23: 10, 4: 6, 2: 5, 42: 5, 1: 4, 3: 4, 34: 4, 234: 3, 423: 3, 5: 2, 12: 2, 123: 1, 31: 1, 13: 1})
Using collections.Counter - Duration: 15.889999999999418
Run Code Online (Sandbox Code Playgroud)
#Solution 3 - Slow
Run Code Online (Sandbox Code Playgroud)
{1: 4, 2: 5, 3: 4, 4: 6, 5: 2, 34: 4, 423: 3, 234: 3, 42: 5, 12: 2, 13: 1, 23: 10, 123: 1, 31: 1}
Using list comprehension - Duration: 33.0
Run Code Online (Sandbox Code Playgroud)

  • @KishanK如果你看到我的答案,我也尝试过使用计数器(解决方案2),但使用循环的解决方案1仍然比它运行得更快。 (2认同)

小智 5

我会使用filter(),以卢卡斯的例子为例:

>>> lst = [1, 2, 3, 4, 1, 4, 1]
>>> len(filter(lambda x: x==1, lst))
3
Run Code Online (Sandbox Code Playgroud)


Gol*_*ion 5

使用 %timeit 查看哪个操作更有效。np.array 计数操作应该更快。

 from collections import Counter
 mylist = [1,7,7,7,3,9,9,9,7,9,10,0] 
 types_counts=Counter(mylist)
 print(types_counts)
Run Code Online (Sandbox Code Playgroud)