python heapq_Python成为专业人士笔记–Heapq 堆操作

“专业人士笔记”系列目录:创帆云:Python成为专业人士笔记--强烈建议收藏!每日持续更新!​zhuanlan.zhihu.com

堆介绍

一种著名的数据结构是堆(heap),它是一种优先队列。优先队列让你能够以任意顺序添加对象,并随时(可能是在两次添加对象之间)找出(并删除)最小的元素。相比于列表方法min,这样做的效率要高得多。

实际上,Python没有独立的堆类型,而只有一个包含一些堆操作函数的模块。这个模块名为heapq(其中的q表示队列),它包含6个函数,其中前4个与堆操作直接相关。必须使用列表来表示堆对象本身。

堆类型类型中最大和最小值

要查找堆中最大的项,heapq模块有一个名为nlargest的函数,我们向它传递两个参数,第一个参数是要返回的元素个数,第二个参数是集合类型变量名

import heapq

numbers = [1, 4, 2, 100, 20, 50, 32, 200, 150, 8]

print(heapq.nlargest(4, numbers))

# 输出:[200, 150, 100, 50]

类似地,为了找到集合烦躁中最小的元素,我们使用 nsmallest函数:

import heapq

numbers = [1, 4, 2, 100, 20, 50, 32, 200, 150, 8]

print(heapq.nsmallest(4, numbers))

#输出:[1, 2, 4, 8】

对于复杂的数据结构,nlargest和 nsmallest 函数都采用一些可选的关键参数。下面的示例演示了如何使用age属性从people字典中检索最年长和最年轻的人

import heapq

people = [

{'firstname': 'John', 'lastname': 'Doe', 'age': 30},

{'firstname': 'Jane', 'lastname': 'Doe', 'age': 25},

{'firstname': 'Janie', 'lastname': 'Doe', 'age': 10},

{'firstname': 'Jane', 'lastname': 'Roe', 'age': 22},

{'firstname': 'Johnny', 'lastname': 'Doe', 'age': 12},

{'firstname': 'John', 'lastname': 'Roe', 'age': 45}

]

oldest = heapq.nlargest(2, people, key=lambda s: s['age'])

print(oldest)

# 输出: [{'firstname': 'John', 'age': 45, 'lastname': 'Roe'}, {'firstname': 'John', 'age': 30,'lastname': 'Doe'}]

#使用了key参数,利用匿名函数将key指定为每个字典元素的age属性

youngest = heapq.nsmallest(2, people, key=lambda s: s['age'])

print(youngest)

# 输出: [{'firstname': 'Janie', 'age': 10, 'lastname': 'Doe'}, {'firstname': 'Johnny', 'age': 12,'lastname': 'Doe'}]

#原理同上

最小元素弹出

堆最有趣的属性是它的最小元素始终是第一个元素:heap [0]

import heapq

numbers = [10, 4, 2, 100, 20, 50, 32, 200, 150, 8]

heapq.heapify(numbers) #将列表就地转换为堆

print(numbers)

# 输出: [2, 4, 10, 100, 8, 50, 32, 200, 150, 20] 堆的第一个元素一定是最小的那个值

heapq.heappop(numbers)

# 删除最小的值最返回:2

print(numbers)

# 输出: [4, 8, 10, 100, 20, 50, 32, 200, 150]

heapq.heappop(numbers)

# 删除最小的值最返回:4

print(numbers)

# 输出: [8, 20, 10, 100, 150, 50, 32, 200]

也许你看到每次输出堆的排列顺序非常随意,其实其并不像看起来的这样。它们虽然不是严格排序的,但必须保证一点:位置i处的元素总是大于位置i // 2处的元素(反过来说就是小于位置2 * i和2 * i + 1处的元素)。这是底层堆算法的基础,称为堆特征(heap property)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值