Question Comment compter les occurrences d'un élément de liste?


Étant donné un élément, comment puis-je compter ses occurrences dans une liste en Python?


1084
2018-04-08 13:30


origine


Réponses:


Si vous ne voulez que le nombre d'un élément, utilisez le count méthode:

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

Ne pas utilisez ceci si vous voulez compter plusieurs éléments. Appel count dans une boucle nécessite un passage séparé sur la liste pour chaque count appel, ce qui peut être catastrophique pour la performance. Si vous voulez compter tous les éléments, ou même simplement plusieurs éléments, utilisez Counter, comme expliqué dans les autres réponses.


1425
2018-04-08 13:31



Si vous utilisez Python 2.7 ou 3 et que vous voulez un nombre d'occurrences pour chaque élément:

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

1359
2018-04-29 07:44



Comptage des occurrences d'un élément dans une liste

Pour compter les occurrences d'un seul élément de liste, vous pouvez utiliser count()

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

Compter les occurrences de tout Les éléments d'une liste sont également connus sous le nom de "comptabilisation" d'une liste ou de création d'un compteur de points.

Comptage de tous les éléments avec count ()

Pour compter les occurrences d'éléments dans l on peut simplement utiliser une compréhension de la liste et la count() méthode

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

(ou similaire avec un dictionnaire dict((x,l.count(x)) for x in set(l)))

Exemple:

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

Comptage de tous les éléments avec Counter ()

Alternativement, il y a le plus rapide Counter classe de la collections bibliothèque

Counter(l)

Exemple:

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

Combien de fois est Counter?

J'ai vérifié combien plus vite Counter est pour les listes de pointage. J'ai essayé les deux méthodes avec quelques valeurs de n et il semble que Counter est plus rapide d'un facteur constant d'environ 2.

Voici le script que j'ai utilisé:

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)

Et la sortie:

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

184
2018-05-28 10:58



Une autre façon d'obtenir le nombre d'occurrences de chaque élément, dans un dictionnaire:

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

56
2017-10-20 22:38



list.count(x) renvoie le nombre de fois x apparaît dans une liste

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


40
2018-04-08 13:34



Si tu veux compter toutes les valeurs à la fois vous pouvez le faire très rapidement en utilisant des tableaux numpy et bincount comme suit

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

qui donne

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

27
2017-11-19 10:53



Étant donné un élément, comment puis-je compter ses occurrences dans une liste en Python?

Voici un exemple de liste:

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

list.count

Il y a le list.count méthode

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

Cela fonctionne très bien pour n'importe quelle liste. Les tuples ont aussi cette méthode:

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

collections.Counter

Et puis il y a des collections.Counter. Vous pouvez vider n'importe quel itérable dans un compteur, pas simplement une liste, et le compteur conservera une structure de données des comptes des éléments.

Usage:

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

Les compteurs sont basés sur des dictionnaires Python, leurs clés sont les éléments, donc les clés doivent être lavables. Ils sont fondamentalement comme des ensembles qui permettent des éléments redondants dans eux.

Autre utilisation de collections.Counter

Vous pouvez ajouter ou soustraire avec des iterables de votre compteur:

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

Et vous pouvez également effectuer des opérations multi-set avec le compteur:

>>> 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})

Pourquoi pas les pandas?

Une autre réponse suggère:

Pourquoi ne pas utiliser les pandas?

Pandas est une bibliothèque commune, mais ce n'est pas dans la bibliothèque standard. L'ajouter en tant que dépendance est non-trivial.

Il existe des solutions intégrées pour ce cas d'utilisation dans l'objet liste lui-même ainsi que dans la bibliothèque standard.

Si votre projet n'exige pas déjà des pandas, il serait stupide d'en faire une exigence uniquement pour cette fonctionnalité.


23
2018-04-13 12:50



J'ai comparé toutes les solutions suggérées (et quelques nouvelles) avec Perfplot (un petit projet de la mienne).

Compte un article

Pour les tableaux suffisamment grands, il s'avère que

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

est légèrement plus rapide que les autres solutions.

enter image description here

Compte tout articles

Comme établi avant,

numpy.bincount(a)

est ce que tu veux.

enter image description here


Code pour reproduire les parcelles:

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



Si vous pouvez utiliser pandas, puis value_counts est là pour le sauvetage.

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

Il trie automatiquement le résultat en fonction de la fréquence.

Si vous voulez que le résultat soit dans une liste de liste, faites comme ci-dessous

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

14
2018-01-17 07:56



Pourquoi ne pas utiliser les pandas?

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

Sortie:

a    3
d    2
b    1
c    1
dtype: int64

Si vous cherchez un compte d'un élément particulier, dites une, essayez:

my_count['a']

Sortie:

3

13
2017-10-17 17:15



J'ai eu ce problème aujourd'hui et roulé ma propre solution avant que je pensais vérifier SO. Ce:

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

est vraiment, vraiment lent pour les grandes listes. Ma solution

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

est en fait un peu plus rapide que la solution Counter, du moins pour Python 2.7.


11
2017-11-07 19:18