Risposte:
Se si desidera un solo conteggio di articoli, utilizzare il countmetodo:
>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3
Non utilizzarlo se si desidera contare più elementi. La chiamata countin un ciclo richiede un passaggio separato sull'elenco per ogni countchiamata, 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 Counterse 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.
isinstancechiama? Anche con milioni di stringhe, chiamare richiede Countersolo una isinstancechiamata, 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 Counterche con un'implementazione manuale. Se vuoi chiamare updatecon 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 luno 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 Counterclasse più veloce dalla collectionslibreria
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 Counterper le liste di conteggio. Ho provato entrambi i metodi con alcuni valori di ne sembra che Countersia 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), Counterdovrebbe 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.countC'è il list.countmetodo
>>> 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.CounterE 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.CounterPuoi 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 acome primo gruppo, mentre altri gruppi di asono presenti più in basso nell'elenco. Ciò accade perché l'elenco di input Lnon è 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 groupbysoluzione. 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_countsimpostato 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 countOfmetodo di un modulo integrato operator.
>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
countOfviene 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]))