Risposte:
Se si desidera un solo conteggio di articoli, utilizzare il count
metodo:
>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3
Non utilizzarlo se si desidera contare più elementi. La chiamata count
in un ciclo richiede un passaggio separato sull'elenco per ogni count
chiamata, che può essere catastrofico per le prestazioni. Se vuoi contare tutti gli articoli, o anche solo più oggetti, usa Counter
, come spiegato nelle altre risposte.
Utilizzare Counter
se si utilizza Python 2.7 o 3.x e si desidera il numero di occorrenze per ciascun elemento:
>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> Counter(z)
Counter({'blue': 3, 'red': 2, 'yellow': 1})
isinstance
. Quindi, se sei sicuro dei dati con cui stai lavorando, potrebbe essere meglio scrivere una funzione personalizzata senza controllo del tipo e dell'istanza.
isinstance
chiama? Anche con milioni di stringhe, chiamare richiede Counter
solo una isinstance
chiamata, per verificare se il suo argomento è una mappatura. Molto probabilmente hai giudicato male ciò che mangia tutto il tuo tempo.
Counter
è andato nel conteggio di grandi iterabili, piuttosto che nel contare molti iterabili. Il conteggio di un iterabile da un milione di stringhe andrà più veloce Counter
che con un'implementazione manuale. Se vuoi chiamare update
con molti iterabili, potresti essere in grado di velocizzare le cose unendole in un unico iterabile itertools.chain
.
Contando le occorrenze di un elemento in un elenco
Per contare le occorrenze di un solo elemento dell'elenco è possibile utilizzare count()
>>> l = ["a","b","b"]
>>> l.count("a")
1
>>> l.count("b")
2
Il conteggio delle occorrenze di tutti gli elementi in un elenco è anche noto come "conteggio" di un elenco o creazione di un contatore di conteggio.
Conteggio di tutti gli articoli con count ()
Per contare le occorrenze di elementi in l
uno si può semplicemente usare una comprensione della lista e il count()
metodo
[[x,l.count(x)] for x in set(l)]
(o in modo simile con un dizionario dict((x,l.count(x)) for x in set(l))
)
Esempio:
>>> 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}
Conteggio di tutti gli articoli con Counter ()
In alternativa, c'è la Counter
classe più veloce dalla collections
libreria
Counter(l)
Esempio:
>>> l = ["a","b","b"]
>>> from collections import Counter
>>> Counter(l)
Counter({'b': 2, 'a': 1})
Quanto è più veloce Counter?
Ho controllato quanto è più veloce Counter
per le liste di conteggio. Ho provato entrambi i metodi con alcuni valori di n
e sembra che Counter
sia più veloce di un fattore costante di circa 2.
Ecco lo script che ho usato:
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)
E l'output:
Counter(): [0.46062711701961234, 0.4022796869976446, 0.3974247490405105]
count(): [7.779430688009597, 7.962715800967999, 8.420845870045014]
Counter
è molto più veloce per elenchi più grandi. Il metodo di comprensione dell'elenco è O (n ^ 2), Counter
dovrebbe essere O (n).
isinstance
. Quindi, se sei sicuro dei dati con cui stai lavorando, potrebbe essere meglio scrivere una funzione personalizzata senza controllo del tipo e dell'istanza.
Un altro modo per ottenere il numero di occorrenze di ciascun elemento, in un dizionario:
dict((i, a.count(i)) for i in a)
n * (number of different items)
operazioni, senza contare il tempo necessario per costruire il set. L'uso collections.Counter
è davvero molto meglio.
i
, perché tenterà di inserire più chiavi dello stesso valore in un dizionario. dict((i, a.count(i)) for i in a)
list.count(x)
restituisce il numero di volte x
appare in un elenco
vedi: http://docs.python.org/tutorial/datastructures.html#more-on-lists
Dato un elemento, come posso contare le sue occorrenze in un elenco in Python?
Ecco un elenco di esempio:
>>> l = list('aaaaabbbbcccdde')
>>> l
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e']
list.count
C'è il list.count
metodo
>>> l.count('b')
4
Funziona bene per qualsiasi elenco. Anche le tuple hanno questo metodo:
>>> t = tuple('aabbbffffff')
>>> t
('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f')
>>> t.count('f')
6
collections.Counter
E poi ci sono le collezioni. Puoi scaricare qualsiasi iterabile in un contatore, non solo in un elenco, e il contatore manterrà una struttura di dati dei conteggi degli elementi.
Uso:
>>> from collections import Counter
>>> c = Counter(l)
>>> c['b']
4
I contatori si basano sui dizionari Python, le loro chiavi sono gli elementi, quindi le chiavi devono essere hash. Sono fondamentalmente come set che consentono di inserire elementi ridondanti.
collections.Counter
Puoi aggiungere o sottrarre con iterables dal tuo contatore:
>>> c.update(list('bbb'))
>>> c['b']
7
>>> c.subtract(list('bbb'))
>>> c['b']
4
E puoi anche eseguire operazioni multi-set con il contatore:
>>> 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})
Un'altra risposta suggerisce:
Perché non usare i panda?
Panda è una libreria comune, ma non è nella libreria standard. L'aggiunta come requisito non è banale.
Esistono soluzioni integrate per questo caso d'uso nell'oggetto elenco stesso e nella libreria standard.
Se il tuo progetto non richiede già i panda, sarebbe sciocco renderlo un requisito solo per questa funzionalità.
Ho confrontato tutte le soluzioni suggerite (e alcune nuove) con perfplot (un mio piccolo progetto).
Per array abbastanza grandi, risulta che
numpy.sum(numpy.array(a) == 1)
è leggermente più veloce rispetto alle altre soluzioni.
numpy.bincount(a)
è quello che vuoi.
Codice per riprodurre i grafici:
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,
)
Se è possibile utilizzare pandas
, allora value_counts
è lì per il salvataggio.
>>> 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
Ordina automaticamente il risultato anche in base alla frequenza.
Se si desidera che il risultato sia in un elenco di elenchi, procedere come di seguito
>>> pd.Series(a).value_counts().reset_index().values.tolist()
[[1, 3], [4, 2], [3, 1], [2, 1]]
Perché non usare i panda?
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
Produzione:
a 3
d 2
b 1
c 1
dtype: int64
Se stai cercando un conteggio di un elemento particolare, dì a , prova:
my_count['a']
Produzione:
3
Ho avuto questo problema oggi e ho lanciato la mia soluzione prima di pensare di controllare SO. Questo:
dict((i,a.count(i)) for i in a)
è davvero molto lento per elenchi di grandi dimensioni. La mia soluzione
def occurDict(items):
d = {}
for i in items:
if i in d:
d[i] = d[i]+1
else:
d[i] = 1
return d
è in realtà un po 'più veloce della soluzione Counter, almeno per Python 2.7.
# 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)]
Il più veloce è usare un ciclo for e memorizzarlo in un 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))
Risultato
#Solution 1 - Faster
{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
#Solution 2 - Fast
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
#Solution 3 - Slow
{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
itertools.groupby()
Un'altra possibilità per ottenere il conteggio di tutti gli elementi nell'elenco potrebbe essere tramite itertools.groupby()
.
Con conteggi "duplicati"
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)
ritorna
[('a', 3), ('t', 1), ('q', 1), ('a', 1), ('d', 1), ('a', 1), ('d', 1), ('c', 1)]
Notate come ha combinato i primi tre a
come primo gruppo, mentre altri gruppi di a
sono presenti più in basso nell'elenco. Ciò accade perché l'elenco di input L
non è stato ordinato. Questo può essere un vantaggio a volte se i gruppi dovessero effettivamente essere separati.
Con conteggi unici
Se si desidera un conteggio di gruppi univoco, è sufficiente ordinare l'elenco di input:
counts = [(i, len(list(c))) for i,c in groupby(sorted(L))]
print(counts)
ritorna
[('a', 5), ('c', 1), ('d', 2), ('q', 1), ('t', 1)]
Nota: per la creazione di conteggi univoci, molte altre risposte forniscono un codice più semplice e più leggibile rispetto alla groupby
soluzione. Ma viene mostrato qui per tracciare un parallelo all'esempio di conteggio duplicato.
È stato suggerito di utilizzare il bincount di numpy , tuttavia funziona solo per array 1d con numeri interi non negativi . Inoltre, l'array risultante potrebbe creare confusione (contiene le occorrenze degli interi dal minimo al massimo dell'elenco originale e imposta a 0 gli interi mancanti).
Un modo migliore per farlo con numpy è usare la funzione unica con l'attributo return_counts
impostato su True. Restituisce una tupla con una matrice di valori univoci e una matrice delle occorrenze di ciascun valore univoco.
# 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]
e quindi possiamo accoppiarli come
dict(zip(a_uniq, counts)) # {0: 2, 1: 3, 2: 1, 3: 2}
Funziona anche con altri tipi di dati e "elenchi 2d", ad es
>>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']]
>>> dict(zip(*np.unique(a, return_counts=True)))
{'a': 3, 'b': 3, 'c': 2}
Anche se è una domanda molto vecchia, ma dato che non ho trovato una copertina, ne ho fatta una.
# 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)
Puoi anche usare il countOf
metodo di un modulo integrato operator
.
>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
countOf
viene implementato? Come si confronta con il più ovvio list.count
(che beneficia dell'implementazione in C)? Ci sono dei vantaggi?
Potrebbe non essere il più efficiente, richiede un passaggio aggiuntivo per rimuovere i duplicati.
Implementazione funzionale:
arr = np.array(['a','a','b','b','b','c'])
print(set(map(lambda x : (x , list(arr).count(x)) , arr)))
ritorna :
{('c', 1), ('b', 3), ('a', 2)}
o ritorna come dict
:
print(dict(map(lambda x : (x , list(arr).count(x)) , arr)))
ritorna :
{'b': 3, 'c': 1, 'a': 2}
sum([1 for elem in <yourlist> if elem==<your_value>])
Ciò restituirà la quantità di occorrenze di your_value
se si desidera un numero di occorrenze per l'elemento particolare:
>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> single_occurrences = Counter(z)
>>> print(single_occurrences.get("blue"))
3
>>> print(single_occurrences.values())
dict_values([3, 2, 1])
def countfrequncyinarray(arr1):
r=len(arr1)
return {i:arr1.count(i) for i in range(1,r+1)}
arr1=[4,4,4,4]
a=countfrequncyinarray(arr1)
print(a)
l2=[1,"feto",["feto",1,["feto"]],['feto',[1,2,3,['feto']]]]
count=0
def Test(l):
global count
if len(l)==0:
return count
count=l.count("feto")
for i in l:
if type(i) is list:
count+=Test(i)
return count
print(Test(l2))
questo conterà ricorsivo o cercherà l'elemento nell'elenco anche se nell'elenco degli elenchi
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]))