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

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

Ответы [ 21 ]

1644 голосов
/ 08 апреля 2010

Если вам нужен только один элемент, используйте метод count:

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

Не используйте это, если хотите посчитать несколько предметов. Для вызова count в цикле требуется отдельный проход по списку для каждого вызова count, что может иметь катастрофические последствия для производительности. Если вы хотите сосчитать все элементы или даже просто несколько элементов, используйте Counter, как объяснено в других ответах.

1552 голосов
/ 29 апреля 2011

Если вы используете Python 2.7 или 3 и вам нужно количество вхождений для каждого элемента:

>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> Counter(z)
Counter({'blue': 3, 'red': 2, 'yellow': 1})
223 голосов
/ 28 мая 2014

Подсчет вхождений одного элемента в списке

Для подсчета вхождений только одного элемента списка вы можете использовать count()

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

Подсчет вхождений всех элементов в списке также называется «подсчетом» списка или созданием счетчика.

Подсчет всех предметов с помощью count ()

Для подсчета вхождений предметов в l можно просто использовать понимание списка и метод count()

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

(или аналогично со словарем dict((x,l.count(x)) for x in set(l)))

Пример:

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

Подсчет всех предметов с помощью счетчика ()

Кроме того, есть более быстрый класс Counter из библиотеки collections

Counter(l)

Пример:

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

Насколько быстрее счетчик?

Я проверил, насколько быстрее Counter для подсчета списков. Я опробовал оба метода с несколькими значениями n, и оказалось, что Counter быстрее с постоянным коэффициентом примерно 2.

Вот скрипт, который я использовал:

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)

И вывод:

Counter():  [0.46062711701961234, 0.4022796869976446, 0.3974247490405105]
count():    [7.779430688009597, 7.962715800967999, 8.420845870045014]
61 голосов
/ 21 октября 2011

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

dict((i, a.count(i)) for i in a)
43 голосов
/ 08 апреля 2010

list.count(x) возвращает количество раз, x появляется в списке

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

34 голосов
/ 13 апреля 2016

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

Вот пример списка:

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

list.count

Это list.count метод

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

Это прекрасно работает для любого списка. У кортежей также есть этот метод:

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

collections.Counter

А потом есть коллекции. Счетчик. Вы можете сбросить любую итерацию в счетчик, а не просто в список, и счетчик сохранит структуру данных счетчиков элементов.

Использование:

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

Счетчики основаны на словарях Python, их ключи являются элементами, поэтому ключи должны быть хэшируемыми. Они в основном похожи на наборы, которые допускают избыточные элементы в них.

Дальнейшее использование collections.Counter

Вы можете добавлять или вычитать с помощью итераций со своего счетчика:

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

И вы можете выполнять множественные операции со счетчиком:

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

Почему не панды?

Другой ответ предполагает:

Почему бы не использовать панд?

Панды - это обычная библиотека, но ее нет в стандартной библиотеке. Добавление его в качестве требования нетривиально.

Для этого варианта использования имеются встроенные решения как в самом объекте списка, так и в стандартной библиотеке.

Если ваш проект еще не требует панд, было бы глупо сделать это требованием только для этой функциональности.

30 голосов
/ 13 сентября 2017

Я сравнил все предложенные решения (и несколько новых) с perfplot (мой небольшой проект).

Подсчет один пункт

Для достаточно больших массивов получается, что

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

немного быстрее, чем другие решения.

enter image description here

Подсчет все предметов

Как установлено ранее ,

numpy.bincount(a)

это то, что вы хотите.

enter image description here


Код для воспроизведения сюжетов:

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,
    )
30 голосов
/ 19 ноября 2013

Если вы хотите считать все значения одновременно , вы можете сделать это очень быстро, используя массивы numpy и bincount следующим образом

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

, что дает

>>> array([0, 3, 1, 1, 2])
18 голосов
/ 17 января 2018

Если вы можете использовать pandas, тогда value_counts там для спасения.

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

Он также автоматически сортирует результаты по частоте.

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

>>> pd.Series(a).value_counts().reset_index().values.tolist()
[[1, 3], [4, 2], [3, 1], [2, 1]]
14 голосов
/ 17 октября 2016

Почему бы не использовать Панд?

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

Выход:

a    3
d    2
b    1
c    1
dtype: int64

Если вы ищете счетчик определенного элемента, скажем a , попробуйте:

my_count['a']

Выход:

3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...