web-dev-qa-db-fra.com

Comment obtenir des valeurs uniques avec un nombre d'occurrences respectif à partir d'une liste en Python?

J'ai une liste qui contient des éléments récurrents et je souhaite une liste des éléments uniques avec leur fréquence 

Par exemple, j'ai ['a', 'a', 'b', 'b', 'b'] et je veux [('a', 2), ('b', 3)].

Vous cherchez un moyen simple de le faire sans avoir à boucler deux fois. 

32
Samantha Green

Si vos éléments sont regroupés (par exemple, des éléments similaires sont regroupés), la méthode la plus efficace à utiliser est itertools.groupby:

>>> [(g[0], len(list(g[1]))) for g in itertools.groupby(['a', 'a', 'b', 'b', 'b'])]
[('a', 2), ('b', 3)]
11
Eli Bendersky

Avec Python 2.7+, vous pouvez utiliser collections.Counter .

Sinon, voir cette recette de compteur .

Sous Python 2.7+:

from collections import Counter
input =  ['a', 'a', 'b', 'b', 'b']
c = Counter( input )

print( c.items() )

La sortie est:

[('a', 2), ('b', 3)]

60
Mark
>>> mylist=['a', 'a', 'b', 'b', 'b']
>>> [ (i,mylist.count(i)) for i in set(mylist) ]
[('a', 2), ('b', 3)]
9
ghostdog74

la "vieille école".

>>> alist=['a', 'a', 'b', 'b', 'b']
>>> d={}
>>> for i in alist:
...    if not d.has_key(i): d[i]=1  #also: if not i in d
...    else: d[i]+=1
...
>>> d
{'a': 2, 'b': 3}
3
ghostdog74

Si vous souhaitez utiliser une bibliothèque tierce, NumPy constitue une solution pratique. Ceci est particulièrement efficace si votre liste ne contient que des données numériques.

import numpy as np

L = ['a', 'a', 'b', 'b', 'b']

res = list(Zip(*np.unique(L, return_counts=True)))

# [('a', 2), ('b', 3)]

Pour comprendre la syntaxe, notez np.unique here renvoie un tuple de valeurs uniques et compte:

uniq, counts = np.unique(L, return_counts=True)

print(uniq)    # ['a' 'b']
print(counts)  # [2 3]

Voir aussi: Quels sont les avantages de NumPy par rapport aux listes Python classiques?

3
jpp

Je sais que ce n'est pas un one-line ... mais j'aime ça parce qu'il m'est clair que nous passons une fois la liste de valeurs initiale (au lieu d'appeler, comptez dessus):

>>> from collections import defaultdict
>>> l = ['a', 'a', 'b', 'b', 'b']
>>> d = defaultdict(int)
>>> for i in l:
...  d[i] += 1
... 
>>> d
defaultdict(<type 'int'>, {'a': 2, 'b': 3})
>>> list(d.iteritems())
[('a', 2), ('b', 3)]
>>>
2
Tom

Avec l'aide de pandas, vous pouvez faire comme:

import pandas as pd
dict(pd.value_counts(my_list))
2
zashishz

Une solution sans hachage:

def lcount(lst):
   return reduce(lambda a, b: a[0:-1] + [(a[-1][0], a[-1][1]+1)] if a and b == a[-1][0] else a + [(b, 1)], lst, [])

>>> lcount([])
[]
>>> lcount(['a'])
[('a', 1)]
>>> lcount(['a', 'a', 'a', 'b', 'b'])
[('a', 3), ('b', 2)]
1
arte

Convertissez n’importe quelle structure de données en une série de pandas:

CODE:

for i in sort(s.value_counts().unique()):
  print i, (s.value_counts()==i).sum()
1
Ali Arar

Une autre façon de faire serait

mylist = [1, 1, 2, 3, 3, 3, 4, 4, 4, 4]
mydict = {}
for i in mylist:
    if i in mydict: mydict[i] += 1
    else: mydict[i] = 1

puis pour obtenir la liste des n-uplets,

mytups = [(i, mydict[i]) for i in mydict]

Cela ne passe qu'une fois sur la liste, mais il doit également parcourir le dictionnaire une fois. Cependant, étant donné qu'il y a beaucoup de doublons dans la liste, le dictionnaire devrait être beaucoup plus petit et donc plus rapide à parcourir.

Néanmoins, je vais admettre que ce n'est pas un code très joli ou concis.

1
Aaron

Voici un moyen:

your_list = ['a', 'a', 'b', 'b', 'b']

count_dictionary = {}

for letter in your_list:

    if letter in count_dictionary:

        count_dictionary[letter] +=1 

    else:

        count_dictionary[letter] = 1
0
Dubem Ezeh