python内置函数返回序列中最大元素_如何查找序列中最大的N个元素,Python模块heapq的使用方法及场合...

今天的内容很简单,我们有一个序列,如何找到该序列中最大或者最小的N个元素?千万别走开,看到后面会有干货分享哦!

这种排序真的简单吗?

一个例子

先举个例子

l = [1,2,4,3,6,0,5,7,9]

该列表中的组大值

>>>print(max(l))

9

该列表中的最小值

>>>print(min(l))

问题来了,我们想知道该列表中最大的3个值或者最小的3个值该怎么办呢?

一般方法

# 先对序列进行排序

sorted(l)

# 然后打印输出

>>>print("前三个:{},后三个:{}".format(l[:3], l[-3:]))

前三个:[1, 2, 4],后三个:[5, 7, 9]

成功实现。

但仅仅这样就可以了吗?我们的干货还没出现呢?先给大家推荐一入门书,里面有很多案例,涉及一些pygame模块的实战项目,感兴趣的朋友们关注下,喜欢阅读正版Python书的朋友们可以入手哦。

接着上面的内容。我们继续……例子扩展

上面的简单列表我们通过排序可以实现,但是复杂一点的列表呢?

复杂一点的例子?

复杂列表如下:

scoreInfo=[

{'name':'Lucy','en_score': 89.6,'math_scroe':94.1},

{'name':'Bob','en_score': 72.4,'math_scroe':84.2},

{'name':'LiLei','en_score': 82.6,'math_scroe':74.1},

{'name':'HanMeimei','en_score': 65.6,'math_scroe':86.9},

{'name':'Lily','en_score': 78.1,'math_scroe':65.8},

{'name':'Tracy','en_score': 72.6,'math_scroe':65.4},

]

按照英语成绩'en_score'对学生进行排名,找出前3名和后3名。

解决方案

仍然使用上面的排序思路:先将列表按照每一项中的'en_score'进行排序,然后输出前后三个即可。对于字典排序,我们前面讲过(参见杂乱无章的数据结构如何进行排序,简明讲述Python字典排序那些事)

还是排序

实现如下:

t_scoreInfo = sorted([item for item in scoreInfo], key=lambda x: x['en_score'], reverse=True)

>>>print('前三个:{}\n后三个:{}'.format(t_scoreInfo[:3], t_scoreInfo[-3:]))

前三个:[{'name': 'Lucy', 'en_score': 89.6, 'math_scroe': 94.1}, {'name': 'LiLei', 'en_score': 82.6, 'math_scroe': 74.1}, {'name': 'Lily', 'en_score': 78.1, 'math_scroe': 65.8}]

后三个:[{'name': 'Tracy', 'en_score': 72.6, 'math_scroe': 65.4}, {'name': 'Bob', 'en_score': 72.4, 'math_scroe': 84.2}, {'name': 'HanMeimei', 'en_score': 65.6, 'math_scroe': 86.9}]

成功完成!

这样就完了?

上面的方法貌似都可以实现该需求,还有别的方案吗?我们知道,碰到类似的问题,应该向内置函数求解。没错,内置函数提供了这样的方法。

还没结束!

导入模块

import heapq

简单序列

l = [1,2,4,3,6,0,5,7,9]

>>>print('前三:{}'.format(heapq.nlargest(3, l)))

前三:[9, 7, 6]

>>>print('后三:{}'.format(heapq.nsmallest(3, l)))

后三:[0, 1, 2]

复杂序列

还是scoreInfo列表

high =heapq.nlargest(3,scoreInfo,key=lambdas:s['en_score'])

low = heapq.nsmallest(3, scoreInfo, key=lambda s: s['en_score'])

>>>print("前三:{}\n后三:{}".format(high, low))

前三:[{'name': 'Lucy', 'en_score': 89.6, 'math_scroe': 94.1}, {'name': 'LiLei', 'en_score': 82.6, 'math_scroe': 74.1}, {'name': 'Lily', 'en_score': 78.1, 'math_scroe': 65.8}]

后三:[{'name': 'HanMeimei', 'en_score': 65.6, 'math_scroe': 86.9}, {'name': 'Bob', 'en_score': 72.4, 'math_scroe': 84.2}, {'name': 'Tracy', 'en_score': 72.6, 'math_scroe': 65.4}]

完美解决,没错,你没看错,都是一行代码!

So Easy!

heapq模块

上面的方法中nlargest()和nsmallest()函数的底层实现是:先将序列数据进行堆排序后放入一个列表中,本质上来讲也是多种方法的封装。

需要强调的是,当我们使用type查看上面的high和low的类型时,返回的是。因此,通过传入序列,此函数使用到了堆结构特性去处理该序列,而返回结果类型依然是该序列本身的类型。

对于一个堆heap的数据结构有以下优点:

heap[0]永远是最小的元素其余元素可通过调用 heapq.heappop()方法得到,该方法会先将第一个元素弹出来,然后用下一个最小的元素来取代被弹出元素(这种操作时间复杂度仅仅是O(log N),N是堆大小)通过上面的描述,如果查找最小的三个元素,其实等价于分别从堆结构中使用heappop()方法弹出3个值即可。

我们先来详细了解下模块heapq提供的接口有哪些……

如何使用

【如何创建堆】

方法一:使用heappush()方法

heap = []

data = [2,3,5,7,9,23,14,16,12,10]

for i in data:

heapq.heappush(heap,i)

>>>print(heap)

[2, 3, 5, 7, 9, 23, 14, 16, 12, 10]

此时,其实并没有进行排序

方法二:使用heapify()方法

data = [2,3,5,7,9,23,14,16,12,10]

heapq.heapify(data)

此时,直接变换data数据为堆结构,并没有返回新的数据

【堆如何排序】

如何排序

方法一:

使用heapq.nlargest()和heapq.nsmallest()方法即可实现。

heapq.nXXXest(num, set, key)

num:表示返回数据的个数

set:表示要处理的序列(当然集合最好,没有重复元素)

key:表示排序规则

方法二:

我们使用heappop()可以弹出heap中的数据。此时,弹出的数据就是排序后的数据。

lst = []

while heap:

lst.append(heapq.heappop(heap))

>>>print(lst)

[2, 3, 5, 7, 9, 10, 12, 14, 16, 23]

怎么样,是不是很神奇?

能读到这里,说明你真的喜欢Python,想学习点干货,看下面……

各种排序场合应用

对heapq使用场合给出几点建议:

好东西分享给大家

查找(排序)元素个数相对序列较小时,函数 nlargest()和 nsmallest()是最佳选择;查找序列唯一的最小、最大的元素,推荐使用min()和max()函数最快。查找(排序)元素个数和序列个数接近时,先排序、再切片,这样会更快。

一个问题

创建一个简单堆,使用heapify(lst)即可。

大家自己解决

如果需要把复杂的列表,如上面的scoreInfo直接传入heapify(scoreInfo)这样是会抛出异常的,异常信息为:

“TypeError: '

这个该如何解决呢?小伙伴们有没有好办法实现?欢迎下方留下宝贵意见。

好了,今天的内容就到这里了,我们通过一个简单的排序案例,讲解了利用堆结构排序的方法。小伙伴们Get到这个技能了吗?上面的问题有没有小伙伴会的?希望不吝赐教,大家共同学习进步。喜欢Python编程的小伙伴关注我,后续有更加精彩的内容推出。

转载请注明出处,百家号:Python高手养成

你可能感兴趣的:(python内置函数返回序列中最大元素_如何查找序列中最大的N个元素,Python模块heapq的使用方法及场合...)