# python concatenare - Come contare le occorrenze di un elemento della lista?

## liste unire (19)

Ho confrontato tutte le soluzioni suggerite (e alcune nuove) con perfplot (un mio piccolo progetto).

### Conteggio di un oggetto

Per array abbastanza grandi, si scopre che

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

è leggermente più veloce rispetto alle altre soluzioni.

### Conteggio di tutti gli oggetti

Come stabilito in precedenza ,

``````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,
)
``````

Dato un oggetto, come posso contare le sue occorrenze in una lista in Python?

se vuoi un numero di occorrenze per l'elemento in 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])
``````

È stato suggerito di utilizzare il bincount di bincount , tuttavia funziona solo per gli array 1d con numeri interi non negativi . Inoltre, l'array risultante potrebbe confondere (contiene le occorrenze dei numeri interi da min a max dell'elenco originale e imposta a 0 gli interi mancanti).

Un modo migliore per farlo con numpy è utilizzare la funzione unique con l'attributo `return_counts` impostato su True. Restituisce una tupla con una matrice di valori univoci e una matrice di 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 "liste 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}
``````

`list.count(x)` restituisce il numero di volte in cui `x` appare in una lista

Perché non usare 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 particolare elemento, ad esempio a , prova:

``````my_count['a']
``````

Produzione:

``````3
``````

Un altro modo per ottenere il numero di occorrenze di ciascun elemento, in un dizionario:

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

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

Se stai usando Python 2.7 o 3 e vuoi il numero di occorrenze per ogni elemento:

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

Se puoi usare i `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 in base alla frequenza.

Se vuoi che il risultato sia in una lista di liste, fai come sotto

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

``````sum([1 for elem in <yourlist> if elem==<your_value>])
``````

Ciò restituirà la quantità di occorrenze di your_value

``````from collections import Counter
country=['Uruguay', 'Mexico', 'Uruguay', 'France', 'Mexico']
count_country = Counter(country)
output_list= []

for i in count_country:
output_list.append([i,count_country[i]])
print output_list
``````

Lista di uscita:

``````[['Mexico', 2], ['France', 1], ['Uruguay', 2]]
``````

# Dato un oggetto, come posso contare le sue occorrenze in una lista 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 metodo `list.count`

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

Questo funziona bene per qualsiasi lista. 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 collezioni.Counter. È possibile 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 sono basati su dizionari Python, le loro chiavi sono gli elementi, quindi le chiavi devono essere lavabili. Sono fondamentalmente come insiemi che consentono di inserire elementi ridondanti.

### Ulteriore utilizzo di `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 fare 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})
``````

## Perché non i panda?

Un'altra risposta suggerisce:

Perché non usare i panda?

Pandas è una libreria comune, ma non è nella libreria standard. Aggiungerlo come requisito non è banale.

Esistono soluzioni integrate per questo caso d'uso nell'oggetto list stesso e nella libreria standard.

Se il tuo progetto non richiede già dei panda, sarebbe sciocco renderlo un requisito solo per questa funzionalità.

## Di seguito sono le tre soluzioni:

Il più veloce utilizza un ciclo for e lo memorizza 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
``````

``````# 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)]
``````

## Conta di tutti gli elementi con `itertools.groupby()`

La possibilità di Antoher per ottenere il conteggio di tutti gli elementi nell'elenco potrebbe essere tramite `itertools.groupby()` .

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 essere separati.

Conteggi unici

Se sono desiderati conteggi di gruppo univoci, basta 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)]
``````

Conteggio delle occorrenze di un elemento in un elenco

Per contare le occorrenze di un solo elemento della lista puoi usare `count()`

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

Il conteggio delle occorrenze di tutti gli elementi in una lista è anche noto come "conteggio" di un elenco o creazione di un contatore di conteggi.

Conteggio di tutti gli articoli con conteggio ()

Per contare le occorrenze di elementi in `l` si può semplicemente usare una comprensione di lista e il metodo `count()`

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

(o similmente 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 elementi con Contatore ()

In alternativa, c'è la classe `Counter` più veloce dalla libreria delle `collections`

``````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 è il `Counter` per le liste di controllo. 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]
``````

Se si desidera contare tutti i valori contemporaneamente, è possibile farlo molto velocemente utilizzando gli array e il `bincount` come segue

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

che dà

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

È inoltre possibile utilizzare il metodo `countOf` di un `operator` modulo incorporato.

``````>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
``````

Se si desidera una nuova lista mantenendo le due vecchie liste:

``````def concatenate_list(listOne, listTwo):
joinedList = []
for i in listOne:
joinedList.append(i)
for j in listTwo:
joinedList.append(j)

sorted(joinedList)

return joinedList
``````