Python 从具有最大int值的对(字符串,int)列表中查找字符串集
我有一个Python 从具有最大int值的对(字符串,int)列表中查找字符串集,python,string,set,max,Python,String,Set,Max,我有一个(str,int)对的列表 list_word=[('AND',1),('BECAUSE',1),('OF',1),('AFRIAD',1),('NEVER',1),('CATS',2),('ARE',2),('FRIENDS',1),('DOGS',2)] 这基本上就是说每个单词在一篇文章中出现了多少次 我想得到的是一组出现次数最多的单词以及出现次数最多的单词。在上面的例子中,我想 (集合(['CATS','DOGS','ARE']),2) 我能想到的解决办法是循环浏览列表。但是有什么
(str,int)
对的列表
list_word=[('AND',1),('BECAUSE',1),('OF',1),('AFRIAD',1),('NEVER',1),('CATS',2),('ARE',2),('FRIENDS',1),('DOGS',2)]
这基本上就是说每个单词在一篇文章中出现了多少次
我想得到的是一组出现次数最多的单词以及出现次数最多的单词。在上面的例子中,我想
(集合(['CATS','DOGS','ARE']),2)
我能想到的解决办法是循环浏览列表。但是有什么优雅的方法可以做到这一点吗?两次线性扫描,首先找到最大元素:
maxcount = max(map(itemgetter(1), mylist))
然后,第二次拉出您关心的值:
maxset = {word for word, count in mylist if count == maxcount}, maxcount
如果您需要获得的集合不止是最大计数,您可以使用在一次传递中按计数累积:
from collections import defaultdict
sets_by_count = defaultdict(set)
for word, count in mylist:
sets_by_count[count].add(word)
然后,它后面可以是
allcounts=sorted(set_by_count.items(),key=itemgetter(0),reverse=True)
以获得计数列表,从最高计数到最低计数(排序工作最少,因为它只对与唯一计数相等的项目进行排序,而不是对所有单词进行排序)。两次线性扫描,首先找到最大元素:
maxcount = max(map(itemgetter(1), mylist))
然后,第二次拉出您关心的值:
maxset = {word for word, count in mylist if count == maxcount}, maxcount
如果您需要获得的集合不止是最大计数,您可以使用在一次传递中按计数累积:
from collections import defaultdict
sets_by_count = defaultdict(set)
for word, count in mylist:
sets_by_count[count].add(word)
然后,后面可以是allcounts=sorted(sets_by_count.items(),key=itemgetter(0),reverse=True)
获取count的列表,设置对,从最高到最低计数(排序工作最少,因为它只对与唯一计数相等的项目进行排序,而不是对所有单词进行排序).将列表
转换为目录
,键作为计数,值作为单词集。找到键的max
值,并将其删除;s对应值
from collections import defaultdict
my_list = [('AND', 1), ('BECAUSE', 1), ('OF', 1), ('AFRIAD', 1), ('NEVER', 1), ('CATS', 2), ('ARE', 2), ('FRIENDS', 1), ('DOGS', 2)]
my_dict = defaultdict(set)
for k, v in my_list:
my_dict[v].add(k)
max_value = max(my_dict.keys())
print (my_dict[max_value], max_value)
# prints: (set(['CATS', 'ARE', 'DOGS']), 2)
将list
转换为dict
,键作为计数,值作为单词集。找到键的max
值,并将其删除;s对应值
from collections import defaultdict
my_list = [('AND', 1), ('BECAUSE', 1), ('OF', 1), ('AFRIAD', 1), ('NEVER', 1), ('CATS', 2), ('ARE', 2), ('FRIENDS', 1), ('DOGS', 2)]
my_dict = defaultdict(set)
for k, v in my_list:
my_dict[v].add(k)
max_value = max(my_dict.keys())
print (my_dict[max_value], max_value)
# prints: (set(['CATS', 'ARE', 'DOGS']), 2)
虽然更多的pythonic解决方案当然更容易看到,但不幸的是,对两次扫描或构建您并不真正想要的数据结构的要求要慢得多
以下相当枯燥的解决方案比dict解决方案快约55%,比基于提供的示例数据(以及我的实现、机器、基准测试等)的基于理解的解决方案快约70%
这几乎可以肯定是一次扫描,而不是两次扫描
word_occs = [
('AND', 1), ('BECAUSE', 1), ('OF', 1), ('AFRIAD', 1), ('NEVER', 1),
('CATS', 2), ('ARE', 2), ('FRIENDS', 1), ('DOGS', 2)
]
def linear_scan(word_occs):
max_val = 0
max_set = None
for word, occ in word_occs:
if occ == max_val:
max_set.add(word)
elif occ > max_val:
max_val, max_set = occ, {word}
return max_set, max_val
平心而论,它们都非常快,在您的情况下,可读性可能更重要。虽然更具pythonic风格的解决方案显然更容易看到,但不幸的是,需要两次扫描,或者构建您并不真正想要的数据结构的速度要慢得多
以下相当枯燥的解决方案比dict解决方案快约55%,比基于提供的示例数据(以及我的实现、机器、基准测试等)的基于理解的解决方案快约70%
这几乎可以肯定是一次扫描,而不是两次扫描
word_occs = [
('AND', 1), ('BECAUSE', 1), ('OF', 1), ('AFRIAD', 1), ('NEVER', 1),
('CATS', 2), ('ARE', 2), ('FRIENDS', 1), ('DOGS', 2)
]
def linear_scan(word_occs):
max_val = 0
max_set = None
for word, occ in word_occs:
if occ == max_val:
max_set.add(word)
elif occ > max_val:
max_val, max_set = occ, {word}
return max_set, max_val
平心而论,它们都非常快,在您的情况下,可读性可能更重要。调用变量list
可能是一件危险的事情。啊,感谢您指出。我写这篇文章只是为了简单明了。现在编辑调用变量列表
可能是一件危险的事情。啊,谢谢你指出。我写这篇文章只是为了简单明了。现在编辑