Bagaimana saya bisa menghitung kemunculan sebuah daftar item?

Diberikan sebuah item, bagaimana saya bisa menghitung kejadian dalam daftar di Python?

Larutan

Jika anda hanya ingin satu item's menghitung, gunakan menghitung metode:

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

Don't gunakan ini jika anda ingin menghitung beberapa item. Panggilan hitung dalam lingkaran membutuhkan terpisah melewati daftar untuk setiap menghitung call, yang dapat menjadi bencana bagi kinerja. Jika anda ingin menghitung semua item, atau bahkan hanya beberapa item, gunakan Counter, sebagaimana dijelaskan dalam jawaban yang lain.

Komentar (1)

Jika anda menggunakan Python 2.7 atau 3 dan anda ingin jumlah kejadian untuk masing-masing elemen:

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

Menghitung kejadian dari satu item dalam daftar

Untuk menghitung kejadian dari salah satu daftar item anda dapat menggunakan count()

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

Menghitung kejadian dari semua item dalam daftar ini juga dikenal sebagai "menghitung-hitung", daftar, atau membuat tally counter.

Menghitung semua item dengan count()

Untuk menghitung kemunculan item dalam l satu hanya dapat menggunakan daftar pemahaman dan count() metode

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

(atau sama dengan kamus dict((x,l.count(x)) for x in set(l)))

Contoh:

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

Menghitung semua item dengan Counter()

Selain itu, ada's lebih cepat Counter kelas dari koleksi perpustakaan

Counter(l)

Contoh:

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

Seberapa cepat adalah Counter?

Aku memeriksa seberapa cepat Counter untuk menghitung-hitung daftar. Aku mencoba kedua metode dengan beberapa nilai-nilai n dan tampaknya bahwa Counter lebih cepat dengan faktor konstan kira-kira 2.

Berikut adalah script yang saya gunakan:

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)

Dan output:

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

Cara lain untuk mendapatkan jumlah kejadian dari masing-masing item, dalam kamus:

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

daftar.count(x) mengembalikan jumlah kali x muncul di daftar

lihat: http://docs.python.org/tutorial/datastructures.html#more-on-lists

Komentar (0)

Diberikan barang, bagaimana saya bisa menghitung kejadian dalam daftar di Python?

Berikut ini's contoh daftar:

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

daftar.count

Ada's daftar.menghitung metode

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

Ini bekerja dengan baik untuk setiap daftar. Tuple memiliki metode ini juga:

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

koleksi.Counter

Dan kemudian ada's koleksi.Counter. Anda dapat membuang iterable ke Counter, tidak hanya daftar, dan Counter akan mempertahankan struktur data penting dari unsur-unsur.

Penggunaan:

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

Counter yang berbasis pada Python kamus, kunci mereka adalah unsur-unsur, sehingga kunci-kunci harus hashable. Mereka pada dasarnya seperti set yang memungkinkan berlebihan elemen ke mereka.

Penggunaan lebih lanjut dari koleksi.Counter

Anda dapat menambah atau mengurangi dengan iterables dari counter anda:

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

Dan anda dapat melakukan multi-operasi set dengan meja serta:

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

Mengapa tidak panda?

Jawaban lain menunjukkan:

Mengapa tidak menggunakan panda?

Panda adalah perpustakaan umum, tapi itu's tidak di perpustakaan standar. Menambahkan itu sebagai persyaratan adalah non-sepele.

Ada builtin solusi untuk ini use case dalam daftar objek itu sendiri serta di perpustakaan standar.

Jika proyek anda sudah tidak memerlukan panda, itu akan menjadi bodoh untuk membuat sebuah kebutuhan, hanya untuk fungsi ini.

Komentar (1)

Jika anda ingin menghitung semua nilai-nilai sekaligus anda dapat melakukannya dengan sangat cepat menggunakan numpy array dan bincount sebagai berikut

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

yang memberikan

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

I've dibandingkan semua solusi yang disarankan (dan beberapa yang baru) dengan perfplot (proyek kecil saya).

Menghitung one item

Untuk yang cukup besar array, ternyata

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

sedikit lebih cepat daripada solusi lain.

Menghitung all item

Sebagaimana ditetapkan sebelum,

numpy.bincount(a)

adalah apa yang anda inginkan.


Kode untuk memunculkan plot:

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

Jika anda dapat menggunakan panda, kemudian value_counts ada untuk menyelamatkan.

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

Secara otomatis macam hasil berdasarkan frekuensi juga.

Jika anda ingin hasil yang akan di daftar dari daftar, lakukan seperti di bawah ini

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

Mengapa tidak menggunakan 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

Output:

a    3
d    2
b    1
c    1
dtype: int64

Jika anda mencari untuk menghitung elemen tertentu, katakanlah a, cobalah:

my_count['a']

Output:

3
Komentar (0)

Aku punya masalah ini hari ini dan digulung saya sendiri solusi sebelum aku berpikir untuk check-JADI. Ini:

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

ini benar-benar, benar-benar lambat untuk daftar besar. Solusi saya

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

sebenarnya sedikit lebih cepat dari Counter solusi, setidaknya untuk Python 2.7.

Komentar (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)]
Komentar (4)

Menghitung semua elemen dengan itertools.groupby()

Batu possiblity untuk mendapatkan hitungan dari semua unsur-unsur dalam daftar bisa dengan cara itertools.groupby().

Dengan "duplikat" jumlah

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)

Kembali

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

Perhatikan bagaimana itu gabungan tiga pertama a's seperti kelompok pertama, sedangkan kelompok lain a yang hadir lebih jauh ke bawah daftar. Hal ini terjadi karena input daftar L tidak diurutkan. Ini bisa menjadi manfaat yang kadang-kadang jika kelompok-kelompok yang seharusnya terpisah.

Dengan jumlah

Jika kelompok yang unik jumlah yang diinginkan, hanya mengurutkan daftar masukan:

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

Kembali

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

Catatan: Untuk menciptakan yang unik, penting, banyak jawaban yang lain memberikan kemudahan dan kode lebih mudah dibaca dibandingkan dengan groupby solusi. Tapi yang ditampilkan di sini untuk menarik paralel untuk duplikat menghitung contoh.

Komentar (0)

Berikut ini adalah tiga solusi:

Tercepat adalah dengan menggunakan loop for dan menyimpannya dalam sebuah 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))

Hasil

Solusi 1 - lebih Cepat

{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

2 Solusi - Cepat

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

Solusi 3 - Lambat

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

Untuk menghitung jumlah elemen yang beragam memiliki jenis umum:

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

memberikan

3 , bukan 6

Komentar (0)

Ia menyarankan untuk menggunakan numpy's bincount, namun ia bekerja hanya untuk 1d array dengan non-negatif bilangan bulat. Juga, array yang dihasilkan mungkin akan membingungkan (mengandung kemunculan bilangan bulat dari min max asli daftar, dan set ke 0 yang hilang bilangan bulat).

Cara yang lebih baik untuk melakukannya dengan numpy adalah dengan menggunakan unik fungsi dengan atribut return_counts set ke True. Kembali sebuah tuple dengan sebuah array dari nilai-nilai unik dan sebuah array dari kemunculan setiap nilai yang unik.

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

dan kemudian kita dapat memasangkan mereka sebagai

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

Ia juga bekerja dengan tipe data lain dan "2d daftar", misalnya

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

Anda juga dapat menggunakan countOf metode built-in modul operator.

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

Meskipun ini adalah pertanyaan kuno, tapi seperti yang saya didn't menemukan salah satu kapal, saya membuat satu.

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

Mungkin bukan yang paling efisien, membutuhkan tambahan lulus untuk menghapus duplikat.

Pelaksanaan jabatan fungsional :

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

kembali :

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

atau kembali sebagai dict :

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

kembali :

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

Ini akan mengembalikan jumlah kejadian dari your_value

Komentar (0)