Как я могу подсчитать вхождения элемента списка? - PullRequest
1329 голосов
/ 08 апреля 2010

Учитывая элемент, как я могу подсчитать его вхождения в списке в Python?

Ответы [ 21 ]

12 голосов
/ 07 ноября 2011

У меня была эта проблема сегодня, и я нашел собственное решение, прежде чем я решил проверить SO. Это:

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

очень, очень медленно для больших списков. Мое решение

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

на самом деле немного быстрее, чем решение Counter, по крайней мере для Python 2.7.

12 голосов
/ 14 августа 2011
# 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)]
8 голосов
/ 30 октября 2018

Количество всех элементов с itertools.groupby()

Другая возможность получить количество всех элементов в списке может быть с помощью itertools.groupby().

С "двойным" количеством

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)

Возвращает

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

Обратите внимание, как он объединил первые три a в качестве первой группы, в то время как другие группы a присутствуют ниже по списку. Это происходит потому, что список ввода L не был отсортирован. Иногда это может быть полезным, если группы фактически должны быть отдельными.

С уникальным количеством

Если необходимо уникальное количество групп, просто отсортируйте список ввода:

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

Возвращает

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

Примечание: Для создания уникальных подсчетов многие другие ответы предоставляют более простой и читаемый код по сравнению с решением groupby. Но здесь показано, чтобы провести параллель с примером дублирования счета.

6 голосов
/ 14 августа 2011

Для подсчета количества разнообразных элементов, имеющих общий тип:

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, а не 6

5 голосов
/ 22 октября 2018

Было предложено использовать numpy's bincount , однако он работает только для 1d массивов с неотрицательными целыми числами . Кроме того, результирующий массив может сбивать с толку (он содержит вхождения целых чисел от минимального до максимального в исходном списке и устанавливает в 0 отсутствующие целые числа).

Лучший способ сделать это с помощью numpy - использовать уникальную функцию 1008 * с атрибутом return_counts, установленным в значение True. Он возвращает кортеж с массивом уникальных значений и массивом экземпляров каждого уникального значения.

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

и затем мы можем соединить их как

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

Он также работает с другими типами данных и «2d списками», например,

>>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']]
>>> dict(zip(*np.unique(a, return_counts=True)))
{'a': 3, 'b': 3, 'c': 2}
3 голосов
/ 02 ноября 2018

Ниже приведены три решения:

Fastest использует цикл for и сохраняет его в 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))

Результат

#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
3 голосов
/ 18 сентября 2016

Вы также можете использовать countOf метод встроенного модуля operator.

>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
2 голосов
/ 01 марта 2018

Может быть не самым эффективным, требуется дополнительный проход для удаления дубликатов.

Функциональная реализация:

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

возвращает:

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

или вернуть как dict:

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

возвращает:

{'b': 3, 'c': 1, 'a': 2}
1 голос
/ 23 августа 2017
sum([1 for elem in <yourlist> if elem==<your_value>])

Это вернет количество вхождений вашего_значения

0 голосов
/ 07 июля 2018
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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...