Если задан элемент, как подсчитать его вхождения в список в Python?
Если вам нужен только один элемент, используйте метод count
:
>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3
**Не используйте этот метод, если вы хотите подсчитать несколько элементов. Вызов count
в цикле требует отдельного прохода по списку для каждого вызова count
, что может катастрофически сказаться на производительности. Если вы хотите подсчитать все элементы или даже только несколько элементов, используйте Counter
, как объясняется в других ответах.
Если вы используете Python 2.7 или 3 и вам нужно количество вхождений для каждого элемента:
>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> Counter(z)
Counter({'blue': 3, 'red': 2, 'yellow': 1})
Подсчет вхождения одного элемента в списке
Для подсчета вхождений только один элемент списка, вы можете использовать функция count()
>>> l = ["a","b","b"]
>>> l.count("a")
1
>>> l.count("b")
2
Подсчет вхождений все товары в список также известен как "счета" в список, или создать счетчик.
Пересчитав все предметы с count()
Для подсчета вхождений элементов в L
, можно просто использовать список понимание и графа (метод)`
[[x,l.count(x)] for x in set(l)]
(или аналогично со словарем дикт((х,л.граф(X)) для X в комплект(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}
Подсчет всех элементов со счетчиком()
Кроме того, там'S-класса быстрее счетчик
из библиотеки "коллекции"
Counter(l)
Пример:
>>> l = ["a","b","b"]
>>> from collections import Counter
>>> Counter(l)
Counter({'b': 2, 'a': 1})
Насколько быстрее счетчик?
Я проверил, насколько быстрее счетчик
для подсчет. Я пробовал оба способа с нескольких значениях N
и получается, что "встречной" быстрее, постоянным фактором около 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]
list.count(x)
возвращает количество раз, когда x
появляется в списке
см: http://docs.python.org/tutorial/datastructures.html#more-on-lists
данный товар, как я могу считать его вхождения в список в Python?
Здесь'пример списка:
>>> l = list('aaaaabbbbcccdde')
>>> l
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e']
Там's в список.метод count`
>>> l.count('b')
4
Это прекрасно работает для любого списка. Кортежи имеют этот метод, а также:
>>> t = tuple('aabbbffffff')
>>> t
('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f')
>>> t.count('f')
6
коллекции.Счетчик
А потом там'ы коллекции.Счетчик. Вы можете сбросить любой итерируемый на прилавке, а не просто список, а счетчик будет сохранять структуру данных графов элементы.
Использование:
>>> from collections import Counter
>>> c = Counter(l)
>>> c['b']
4
Счетчики на основе Python словари, их ключи являются элементами, так ключи должны быть hashable. Они в основном нравятся наборы, которые позволяют избыточные элементы в них.
Вы можете добавить или вычесть с итерируемых от вашего счетчика:
>>> 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})
Другой ответ предполагает:
почему бы не использовать панд?
Панды-это обычная библиотека, но она's не в стандартной библиотеке. Добавив его как требование нетривиально.
Есть встроенные решения для этого использовать-дело в списке самого объекта, а также в стандартной библиотеке.
Если ваш проект уже не требует панды, было бы глупо принять это требование только для этой функции.
Если вы хотите считать все значения сразу вы можете сделать это очень быстро, используя массивы 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])
Я'вэ сравнить все предложенные решения (и несколько новых) с perfplot (небольшой проект).
Для достаточно больших массивов, то получается, что
в
numpy.sum(numpy.array(a) == 1)
немного быстрее, чем другие решения.
в
numpy.bincount(a)
это то, что вы хотите.
Код, чтобы воспроизвести участков:
в
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,
)
Если вы можете использовать панды
, затем 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]]
Почему бы не использовать панд?
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
Если вы ищете количество определенного элемента, скажем в, попробовать:
my_count['a']
Выход:
3
Сегодня у меня была эта проблема и покатилось мое собственное решение, прежде чем я думал, чтобы проверить так. Это:
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
на самом деле немного быстрее, чем счетчик решение, по крайней мере для Python 2.7.
# 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)]
Другой возможностью для получения количества всех элементов в списке может быть посредством модуле 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)]
Обратите внимание, как он объединил первые три а
's в качестве первой группы, а другие группы " А " присутствуют дальше по списку. Это происходит потому, что входной список " л " не был отсортирован. Это может быть полезным иногда, если группы должны на самом деле быть отдельной.
С уникальным статьям
Если уникальная группа показатели нужные, вроде как входной список:
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
решение. Но он показан здесь провести параллель с дубликата примеру графа.
Самый быстрый-это с помощью цикла for и хранить его в дикт.
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))
Результат
Решение № 1 - быстрее
{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 - быстро
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
решение № 3 - медленно
{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
Было предложено использовать библиотеки numpy'ы bincount, однако он работает только для 1D массивы с целых неотрицательных чисел. Кроме того, результирующий массив может ввести в заблуждение (он содержит вхождений чисел от min до Max оригинального списка, и 0 пропущенные числа).
Лучший способ, чтобы сделать это с и NumPy использовать уникальный Функция с установить атрибут 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}
Он также работает с другими типами данных и "2Д списки" и, напр.
>>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']]
>>> dict(zip(*np.unique(a, return_counts=True)))
{'a': 3, 'b': 3, 'c': 2}
Вы также можете использовать countOf
способ встроенного модуля ["оператор"] (https://docs.python.org/3/library/operator.html).
>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
Хотя это очень старый вопрос, но я не'т найти один вкладыш, я сделал один.
# 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)
Может не быть наиболее эффективным, требуется дополнительный проход, чтобы удалить дубликаты.
Функциональные реализации :
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)}
или вернуться в словарь
:
print(dict(map(lambda x : (x , list(arr).count(x)) , arr)))
возвращает :
{'b': 3, 'c': 1, 'a': 2}
sum([1 for elem in <yourlist> if elem==<your_value>])
Это будет возвращать количество вхождений значение