如何计算列表项出现的次数?
- 2024-11-18 08:41:00
- admin 原创
- 15
问题描述:
给定一个项目,在 Python 中如何计算它在列表中出现的次数?
一个相关但不同的问题是计算集合中每个不同元素的出现次数,将字典或列表作为直方图结果而不是单个整数。对于该问题,请参阅使用字典计算列表中的项目数。
解决方案 1:
如果您只想要单个项目的数量,请使用该count
方法:
>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3
重要提示:如果你要计算多个不同的项目,这会非常慢
每次count
调用都会遍历整个元素列表n
。count
循环调用n
意味着要n * n
进行全面检查,这对于性能来说可能是灾难性的。
如果您要计算多个项目,请使用Counter
,它仅进行n
总体检查。
解决方案 2:
Counter
如果您使用的是 Python 2.7 或 3.x,并且想要了解每个元素的出现次数,请使用:
>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> Counter(z)
Counter({'blue': 3, 'red': 2, 'yellow': 1})
解决方案 3:
计算列表中某项出现的次数
要计算一个列表项的出现次数,您可以使用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() 对所有项目进行计数
Counter
另外,图书馆还有更快的collections
课程
Counter(l)
例子:
>>> l = ["a","b","b"]
>>> from collections import Counter
>>> Counter(l)
Counter({'b': 2, 'a': 1})
Counter 速度有多快?
我检查了计数列表的速度有多快Counter
。我用几个值尝试了这两种方法n
,结果显示Counter
速度大约快了 2 倍。
以下是我使用的脚本:
from __future__ import print_function
import timeit
t1=timeit.Timer('Counter(l)', \n '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]
解决方案 4:
获取字典中每个项目出现次数的另一种方法:
dict((i, a.count(i)) for i in a)
解决方案 5:
给定一个项目,如何计算它在 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
然后是 collections.Counter。您可以将任何可迭代对象转储到 Counter 中,而不仅仅是列表,并且 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})
愚蠢的回答,总结
有很好的内置答案,但这个例子有点启发性。这里我们把字符 c 等于 的所有出现次数相加'b'
:
>>> sum(c == 'b' for c in l)
4
对于这个用例来说不是很好,但如果您需要对情况进行迭代计数,那么True
对布尔结果求和就可以了,因为True
相当于1
。
为什么不是熊猫?
另一个答案建议:
为什么不使用熊猫?
Pandas 是一个通用库,但它不在标准库中。将其添加为要求并非易事。
列表对象本身以及标准库中都有针对此用例的内置解决方案。
如果您的项目还不需要 pandas,那么仅仅为了此功能而将其作为要求是愚蠢的。
解决方案 6:
我将所有建议的解决方案(以及一些新的解决方案)与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))
b = perfplot.bench(
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,
)
b.save("out.png")
b.show()
解决方案 7:
list.count(x)
`x`返回列表中出现的次数
参见:
http: //docs.python.org/tutorial/datastructures.html#more-on-lists
解决方案 8:
如果你想一次性计算所有值,你可以使用 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])
解决方案 9:
为什么不使用 Pandas?
import pandas as pd
my_list = ['a', 'b', 'c', 'd', 'a', 'd', 'a']
# converting the list to a Series and counting the values
my_count = pd.Series(my_list).value_counts()
my_count
输出:
a 3
d 2
b 1
c 1
dtype: int64
如果您要查找特定元素的数量,例如,请尝试:
my_count['a']
输出:
3
解决方案 10:
如果你能使用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]]
解决方案 11:
我今天遇到了这个问题,在我想检查一下之前,我提出了自己的解决方案。这个:
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:
计数所有元素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
。但此处显示的代码与重复计数示例相似。
解决方案 13:
虽然这是一个很老的问题,但由于我没有找到一个单行代码,所以我做了一个。
# 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)
# {1: 1, 2: 2, 3: 3, 4: 1}
解决方案 14:
# 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)]
解决方案 15:
以下是三种解决方案:
最快的是使用 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
解决方案 16:
建议使用 numpy 的bincount,但它仅适用于具有非负整数的1d 数组。此外,生成的数组可能会令人困惑(它包含原始列表中从最小到最大的整数的出现次数,并将缺失的整数设置为 0)。
使用 numpy 执行此操作的更好方法是使用将属性设置为 True 的uniquereturn_counts
函数。它返回一个元组,其中包含唯一值数组和每个唯一值出现的数组。
# 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}
它还适用于其他数据类型和“二维列表”,例如
>>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']]
>>> dict(zip(*np.unique(a, return_counts=True)))
{'a': 3, 'b': 3, 'c': 2}
解决方案 17:
计算具有共同类型的不同元素的数量:
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
解决方案 18:
您也可以使用countOf
内置模块的方法operator
。
>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
解决方案 19:
我会使用filter()
,以 Lukasz 为例:
>>> lst = [1, 2, 3, 4, 1, 4, 1]
>>> len(filter(lambda x: x==1, lst))
3
解决方案 20:
使用 %timeit 来查看哪个操作更有效率。np.array 计数操作应该更快。
from collections import Counter
mylist = [1,7,7,7,3,9,9,9,7,9,10,0]
types_counts=Counter(mylist)
print(types_counts)
解决方案 21:
可能不是最有效的,需要额外传递一次来删除重复项。
功能实现:
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}
解决方案 22:
给定一个列表 X
import numpy as np
X = [1, -1, 1, -1, 1]
显示此列表元素的 i:频率(i)的字典是:
{i:X.count(i) for i in np.unique(X)}
输出:
{-1: 2, 1: 3}
解决方案 23:
mot = ["compte", "france", "zied"]
lst = ["compte", "france", "france", "france", "france"]
dict((x, lst.count(x)) for x in set(mot))
这给出
{'compte': 1, 'france': 4, 'zied': 0}
解决方案 24:
或者,你也可以自己实现计数器。这是我的做法:
item_list = ['me', 'me', 'you', 'you', 'you', 'they']
occ_dict = {}
for item in item_list:
if item not in occ_dict:
occ_dict[item] = 1
else:
occ_dict[item] +=1
print(occ_dict)
输出:{'me': 2, 'you': 3, 'they': 1}
解决方案 25:
sum([1 for elem in <yourlist> if elem==<your_value>])
这将返回 your_value 出现的次数
解决方案 26:
test = [409.1, 479.0, 340.0, 282.4, 406.0, 300.0, 374.0, 253.3, 195.1, 269.0, 329.3, 250.7, 250.7, 345.3, 379.3, 275.0, 215.2, 300.0]
for i in test:
print('{} numbers {}'.format(i, test.count(i)))
解决方案 27:
import pandas as pd
test = [409.1, 479.0, 340.0, 282.4, 406.0, 300.0, 374.0, 253.3, 195.1, 269.0, 329.3, 250.7, 250.7, 345.3, 379.3, 275.0, 215.2, 300.0]
#turning the list into a temporary dataframe
test = pd.DataFrame(test)
#using the very convenient value_counts() function
df_counts = test.value_counts()
df_counts
然后您可以使用df_counts.index
和df_counts.values
来获取数据。
解决方案 28:
x = ['Jess', 'Jack', 'Mary', 'Sophia', 'Karen',
'Addison', 'Joseph','Jack', 'Jack', 'Eric', 'Ilona', 'Jason']
the_item = input('Enter the item that you wish to find : ')
how_many_times = 0
for occurrence in x:
if occurrence == the_item :
how_many_times += 1
print('The occurrence of', the_item, 'in', x,'is',how_many_times)
创建了一个名称列表,其中重复了名称“Jack”。为了检查其出现情况,我在名为的列表中运行了一个 for 循环x
。在每次迭代中,如果循环变量达到与从用户接收并存储在变量中的相同的值the_item
,则变量how_many_times
将增加 1。在达到某个值后...我们打印how_many_times
存储单词“jack”出现的值
解决方案 29:
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)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件