Cum pot număra aparițiile unui element din listă?

Dat un element, cum pot conta sale apariții într-o listă în Python?

Soluția

Dacă doriți doar un element's a conta, de a folosi "count" metoda:

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

Don't utilizați această opțiune dacă doriți să conta mai multe elemente. De asteptare "numere", într-o buclă necesită o separat trece pe lista pentru fiecare "numere", apel, care pot fi catastrofale pentru performanță. Dacă vrei să numeri toate elementele, sau chiar mai multe elemente, utilizați "Counter", cum este explicat în alte răspunsuri.

Comentarii (1)

Dacă sunteți folosind Python 2.7 sau 3 și vrei numărul de apariții pentru fiecare element:

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

Numărarea de evenimente de un element într-o listă

Pentru numărarea aparițiilor doar un element din listă, puteți utiliza count()

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

Numărarea aparițiilor toate articole într-o listă este, de asemenea, cunoscut sub numele de "verifica" - o listă, sau crearea unui contor cu înregistrare.

Numărare toate elementele cu count()

Să numere aparițiile de articole în " l " se poate folosi pur și simplu o listă de înțelegere și `count () metoda

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

(sau, în mod similar cu un dicționar dict((x,l.count(x)) pentru x în set(l)))

Exemplu:

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

Numărare toate elementele cu Contor()

Alternativ, acolo's cel mai rapid "Counter" clasa de "colecții" biblioteca

Counter(l)

Exemplu:

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

Cât de mult mai repede este Contra?

Am verificat cât mai repede "Counter" este pentru listele de numărare a voturilor. Am incercat ambele metode cu câteva valori de " n "și se pare că "Counter" este mai rapid printr-un factor constant de aproximativ 2.

Aici este script-ul am folosit:

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)

Și de ieșire:

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

Un alt mod de a obține numărul de apariții ale fiecărui element, într-un dicționar:

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

lista.count(x) returnează numărul de ori " x " apare într-o listă

a se vedea: http://docs.python.org/tutorial/datastructures.html#more-on-lists

Comentarii (0)

Dat un element, cum pot conta sale apariții într-o listă în Python?

Aici's un exemplu de lista:

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

lista.conta

Nu's pe lista.conta` metoda

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

Aceasta funcționează bine pentru orice listă. Tupluri au această metodă la fel de bine:

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

# colecțiilor.Contra`

Și apoi, nu's colecții.Contra. Puteți arunca orice iterable într-un Contra, nu doar o listă, iar Contorul va păstra o structură de date de numărul de elemente.

Utilizare:

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

Contoare sunt bazate pe Python dicționare, cheile lor sunt elementele, astfel încât cheile trebuie să fie hashable. Ele sunt de fapt seturi care permit elemente redundante în ele.

Utilizarea în continuare a colecțiilor.Contra`

Puteți adăuga sau scădea cu iterables din contra:

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

Și tu poți face multi-set de operațiuni cu tejghea precum:

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

De ce nu panda?

Un alt răspuns sugerează:

de Ce nu folosesc panda?

Panda este o comună de bibliotecă, dar nu's nu în biblioteca standard. Adăugarea ca o cerință este non-trivial.

Există interna solutii pentru acest caz de utilizare în lista obiect în sine, precum și în biblioteca standard.

În cazul în care proiectul nu necesită deja panda, ar fi o prostie să-l facă o cerință doar pentru această funcționalitate.

Comentarii (1)

Daca vrei sa conta toate valorile de la o dată o puteti face foarte rapid, folosind numpy tablouri și bincount, după cum urmează

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

care dă

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

Am'am comparat toate soluțiile propuse (și câteva altele noi) cu perfplot (un mic proiect de-al meu).

De numărare one element

Pentru suficient de mare matrice, se pare că

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

este ușor mai rapid decât alte soluții.

De numărare all elemente

Cum a fost stabilit înainte,

numpy.bincount(a)

este ceea ce vrei.


Cod pentru a reproduce parcele:

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,
    )
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,
    )
Comentarii (1)

Dacă puteți folosi panda", apoi " value_counts` este acolo pentru salvare.

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

Se sortează automat rezultatul în funcție de frecvență, precum și.

Dacă doriți ca rezultatul să fie într-o listă de lista, face ca mai jos

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

De ce nu folosesc 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

Ieșire:

a    3
d    2
b    1
c    1
dtype: int64

Dacă sunteți în căutarea pentru un număr de un anumit element, spun o, încercați:

my_count['a']

Ieșire:

3
Comentarii (0)

Am avut această problemă astăzi și laminate propria mea soluție m-am gândit înainte de a verifica ATÂT. Asta:

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

este foarte, foarte lent pentru liste mari. Soluția mea

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

este de fapt un pic mai repede decât Contra soluție, cel puțin pentru Python 2.7.

Comentarii (2)
# 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)]
Comentarii (4)

Contele de toate elementele cu itertools.groupby()

Un alt posibilitate pentru a obține numărul de toate elementele din listă ar putea fi de mijloace de itertools.groupby()`.

Cu "duplicat" contează

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)

Se întoarce

[('a', 3), ('t', 1), ('q', 1), ('a', 1), ('d', 1), ('a', 1), ('d', 1), ('c', 1)]

Observați cum s-au combinat primele trei " a "'s ca primul grup, în timp ce alte grupuri de " a " sunt prezente mai jos pe lista. Acest lucru se întâmplă deoarece lista de intrare " L " nu a fost rezolvat. Acest lucru poate fi un beneficiu, uneori, dacă grupurile ar trebui să fie separate.

Cu unic contează

Dacă grup unic contează sunt dorite, doar sorta lista de intrare:

counts = [(i, len(list(c))) for i,c in groupby(sorted(L))]
print(counts)

Se întoarce

[('a', 5), ('c', 1), ('d', 2), ('q', 1), ('t', 1)]

Notă: Pentru a crea unic contează, multe alte răspunsuri oferi mai ușor și mai ușor de citit codul comparativ cu `groupby soluție. Dar este prezentat aici pentru a trage o paralelă cu duplicat conta exemplu.

Comentarii (0)

Mai jos sunt trei solutii:

Cel mai rapid este folosind-o pentru buclă și stocarea într-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))

Rezultat

Soluție 1 - mai Repede

{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

Soluția 2 - Rapid

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

Soluție 3 - Lent

{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
Comentarii (0)

Pentru a contoriza numărul de diverse elemente care au un tip comun:

li = ['A0','c5','A8','A2','A5','c2','A3','A9']

print sum(1 for el in li if el[0]=='A' and el[1] in '01234')

3 , nu 6

Comentarii (0)

Acesta a fost sugerat să folosească numpy's bincount, cu toate acestea, ea funcționează doar pentru tablouri 1d cu non-numere întregi negative. De asemenea, rezultă o matrice poate fi confuz (conține evenimente de numere întregi de la min la max de pe lista inițială, și seturi la 0 lipsă numere întregi).

O modalitate mai bună de a face cu numpy este de a utiliza unic funcția cu atributul return_counts setat la True. Returnează un tuplu cu o serie de valori unice și o serie de apariții ale fiecărui valoare unică.

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

și atunci putem pereche-le ca

dict(zip(a_uniq, counts))  # {0: 2, 1: 3, 2: 1, 3: 2}

De asemenea, funcționează cu alte tipuri de date și "2d liste", de exemplu

>>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']]
>>> dict(zip(*np.unique(a, return_counts=True)))
{'a': 3, 'b': 3, 'c': 2}
Comentarii (0)

Puteți folosi, de asemenea, countOf metoda de un built-in modul ["operator"] (https://docs.python.org/3/library/operator.html).

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

Deși este foarte veche întrebare, dar cum am't găsi o linie una, am făcut-o.

# 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)
Comentarii (1)

Nu pot fi cele mai eficiente, necesită o trecere în plus pentru a elimina duplicatele.

Implementarea funcționale :

arr = np.array(['a','a','b','b','b','c'])
print(set(map(lambda x  : (x , list(arr).count(x)) , arr)))

se întoarce :

{('c', 1), ('b', 3), ('a', 2)}

sau de a reveni ca dict :

print(dict(map(lambda x  : (x , list(arr).count(x)) , arr)))

se întoarce :

{'b': 3, 'c': 1, 'a': 2}
Comentarii (0)
sum([1 for elem in  if elem==])

Acest lucru va returna suma de apariții ale your_value

Comentarii (0)