python进阶(数据结构和算法[二])


找到最大或者最小的N个元素

heapq模块有两个函数–nlargest()nsmallest()正好能解决我们的问题。

>>> print(heapq.nlargest(3, nums))
[43, 23, 8]
>>> print(heapq.nsmallest(3,nums))
[-1, 1, 2]

#another

import heapq

portfolio = [
   {‘name‘: ‘IBM‘, ‘shares‘: 100, ‘price‘: 91.1},
   {‘name‘: ‘AAPL‘, ‘shares‘: 50, ‘price‘: 543.22},
   {‘name‘: ‘FB‘, ‘shares‘: 200, ‘price‘: 21.09},
   {‘name‘: ‘HPQ‘, ‘shares‘: 35, ‘price‘: 31.75},
   {‘name‘: ‘YHOO‘, ‘shares‘: 45, ‘price‘: 16.35},
   {‘name‘: ‘ACME‘, ‘shares‘: 75, ‘price‘: 115.65}
]

cheap = heapq.nsmallest(3, portfolio, key=lambda s: s[‘price‘])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s[‘price‘])

print(cheap)
print(expensive)

# 输出

[{‘shares‘: 45, ‘name‘: ‘YHOO‘, ‘price‘: 16.35}, {‘shares‘: 200, ‘name‘: ‘FB‘, ‘price‘: 21.09}, {‘shares‘: 35, ‘name‘: ‘HPQ‘, ‘price‘: 31.75}]
[{‘shares‘: 50, ‘name‘: ‘AAPL‘, ‘price‘: 543.22}, {‘shares‘: 75, ‘name‘: ‘ACME‘, ‘price‘: 115.65}, {‘shares‘: 100, ‘name‘: ‘IBM‘, ‘price‘: 91.1}]

简单的介绍一下heapq中的方法:

import heapq
#heapq.heappush(heap,item)  #heap为定义堆,item 增加的元素;
#eg.
  heap=[]
  heapq.heappush(heap, 2) # heap = [2]
#heapq.heapify(list)        #将列表转换为堆
#eg.
   list=[5,8,0,3,6,7,9,1,4,2]
   heapq.heapify(list)
#heapq.heappop(heap)        #删除最小的值
#eg.
  heap=[2, 4, 3, 5, 7, 8, 9, 6]
  heapq.heappop(heap) ---->heap=[3, 4, 5, 7, 9, 6, 8]
#heapq.heapreplace(heap, item)     #删除最小元素值,添加新的元素值
#eg.
  heap=[2, 4, 3, 5, 7, 8, 9, 6]
  heapq.heapreplace(heap, 11) ------>heap=[2, 3, 4, 6, 8, 5, 7, 9, 11]
#heapq.heappushpop(heap, item)     #首判断添加元素值与堆的第一个元素值对比,如果大于则删除最小元素,然后添加新的元素值,否则不更改堆
#eg.
   条件:item >heap[0]
   heap=[2, 4, 3, 5, 7, 8, 9, 6]
   heapq.heappushpop(heap, 9)---->heap=[3, 4, 5, 6, 8, 9, 9, 7]
   条件:item
   heap=[2, 4, 3, 5, 7, 8, 9, 6]
   heapq.heappushpop(heap, 9)---->heap=[2, 4, 3, 5, 7, 8, 9, 6]
#heapq.merge(...)             #将多个堆合并
#heapq.nlargest (n, heap)     #查询堆中的最大元素,n表示查询元素个数
#eg.
  heap=[2, 3, 5, 6, 4, 8, 7, 9]
  heapq.nlargest (1, heap)--->[9]
#heapq.nsmallest(n, heap)     #查询堆中的最小元素,n表示查询元素个数
#eg.
 heap=[2, 3, 5, 6, 4, 8, 7, 9]
 heapq.nlargest (1, heap)--->[2]

对不一样的数据排序使用不同的方式

  1. 当要查找的元素相对较少时,nlargestnsmallest是最合适的。
  2. 只是想找到最大最小元素,使用minmax是最合适的。
  3. 如果N和集合本身相差不大,使用排序并切片的方式是合适的(sorted(items)[:N]sorted(items)[-N:])。
  4. N相对总元素较少的时候,适合使用将数据转化成列表,元素顺序以堆的顺序排列(参照上述的heapq.heapify())。

实现优先级队列

import heapq # 堆的数据结构,通过对数时间能找到最大或最小元素
class PriorityQueue:
    def __init__(self):
        self._queue = [] #初始化的列表
        self._index = 0 # 初始化的索引,用去比较优先级相同的元素
    def push(self, item, priority):
        # 通过heappush向_queue列表中添加一个元素(元组),默认是小顶堆,因此将优先级取反;
        # 元组比较大小是逐项的,因此添加_index作为相同优先级比较的第二个比较项;永远不会比较第三项
        heapq.heappush(self._queue, (-priority, self._index, item))
        self._index += 1
    def pop(self):
        return heapq.heappop(self._queue)[-1] #弹出的是三元组(-priority, _index, Item(‘‘),只显示最后一项即可

#构造的元素类
class Item:
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return ‘Item({!r})‘.format(self.name)

q = PriorityQueue()
q.push(Item(‘foo‘), 1)
q.push(Item(‘bar‘), 5)
q.push(Item(‘barm‘), 4)
q.push(Item(‘grok‘), 1)
print(q.pop())
print(q.pop())
print(q.pop())
print(q.pop())

输出:

Item(‘bar‘)
Item(‘barm‘)
Item(‘foo‘)
Item(‘grok‘)

从输出中我们看出:是按照优先级输出,相同优先级的按照索引较小的先输出(因为是小顶堆并且先插入的索引值较小)

时间: 2024-10-23 04:36:14

python进阶(数据结构和算法[二])的相关文章

数据结构与算法二

1.课程安排表: 1. 线性表 2. 字符串 3. 栈和队列 4.树 5.查找 6.排序 7.暴力枚举法 8.广度优先搜索 9.深度优先搜索 10.分治 11.贪心 12.动态规划 13.图 14.数学方法与常见模型 15.大整数运算 16. 基础功能 2.   编程技巧: 1.把较大的数组放在main 函数(全局变量)外,作为全局变量,这样可以防止栈溢出,因为栈的大小是有限制的.GCC (C编译器) 段错误 2.如果能够预估栈,队列的上限,则不要用stack,queue,使用数组来模拟,这样速

[0x01 用Python讲解数据结构与算法] 关于数据结构和算法还有编程

忍耐和坚持虽是痛苦的事情,但却能渐渐地为你带来好处. ——奥维德 一.学习目标 · 回顾在计算机科学.编程和问题解决过程中的基本知识: · 理解“抽象”在问题解决过程中的重要作用: · 理解并实现抽象数据结构: · 复习Python编程语言 二.写在前面 自第一台电子计算机使用线路和开关传达人类的指令以来,我们编程的思考方式有了很大的改变,在很多方面,计算机技术的发展为计算机科学家提供了众多的工具和平台去实现他们的想法.高性能理器,高速网络和大内存使得计算机研究者必须掌握在这样复杂的螺旋式通道中

Java数据结构和算法(二)——数组

数组的用处是什么呢?--当你需要将30个数进行大小排列的时候,用数组这样的数据结构存储是个很好的选择,当你是一个班的班主任的时候,每次要记录那些学生的缺勤次数的时候,数组也是很有用.数组可以进行插入,删除,查找等. 1)创建和内存分配 Java中有两种数据类型,基本类型和对象类型,也有人称为引用类型,Java中把数组当成对象,创建数组时使用new操作符. int array[] = new int[10]; 既然是对象,那么array便是数组的一个引用,根据Java编程思想(一) -- 一切都是

[数据结构与算法]二叉排序(搜索)树实现

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4289804.html 定义 二叉排序树又称二叉查找树或二叉搜索树,它或者是一棵空树,或者是具有如下性质的二叉树:1.若它是左子树非空,则左子树上所有节点的值均小于根节点的值2.若它的右子树非空,则右子树上所有节点的值均大于根节点的值3.左.

数据结构和算法二(数组)

一.数组 1.概念 数组是一种线性表数据结构,它用一种连续的内存空间,来存储一组具有相同类型的数据. 线性表:数组.链表.队列.栈等 非线性表:二叉树.堆.图等 2.连续的内存空间和相同类型的数据 优点:具有随机范文的特性,根据下标随机访问的时间复杂度为O(1) 缺点:低效的插入和删除 插入:最好O(1),最坏O(n),平均O(n) 插入:数组若无序,插入新的元素时,可以将第K个位置元素移动到数组末尾,把新的元素插入到第K个位置,此时复杂度为O(1) 删除:最好(1),最坏O(n),平均O(n)

Python实现数据结构和算法之桶排序

桶排序 桶排序从 1956 年就开始被使用,该算法的基本思想是由E.J.Issac 和 R.C.Singleton 提出来的. 这个算法就好比有 11 个桶,编号从 0~10.每出现一个数,就在对应编号的桶中放一个小旗子,最后只要数数每个桶中有几个小旗子就 OK 了.例如 2 号桶中有 1 个小旗子,表示2 出现了一次;3 号桶中有 1 个小旗子,表示 3 出现了一次;5 号桶中有 2 个小旗子,表示 5出现了两次;8 号桶中有 1 个小旗子,表示 8 出现了一次. 代码 1 def main(

Python实现数据结构和算法之冒泡排序

冒泡排序 冒泡排序的基本思想是:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来. 如果有 n 个数进行排序,只需将 n?1 个数归位,也就是说要进行n-1 趟操作.而“每一趟”都需要从第 1 位开始进行相邻两个数的比较,将较小的一个数放在后面,比较完毕后向后挪一位继续比较下面两个相邻数的大小,重复此步骤,直到最后一个尚未归位的数,已经归位的数则无需再进行比较. 代码 1 def _bubbleSort(): 2 a = [] 3 n = int(input('您需要输入几个数进行排序

Python进阶 学习笔记(二)

(涉及内容:面向对象,类的继承) 定义类并创建实例 在Python中,类通过 class 关键字定义.以 Person 为例,定义一个Person类如下: class Person(object): pass 按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的.类的继承将在后面的章节讲解,现在我们只需要简单地从object类继承. 有了Person类的定义,就可以创建出具体的xiaoming.xiaohong等实例.创建实例使用 类名+()

用python语言讲解数据结构与算法总述(一)

关于数据结构与算法讲解的书籍很多,但是用python语言去实现的不是很多,最近有幸看到一本这样的书籍,由Brad Miller and David Ranum编写的<Problem Solving with Algorithms and Data Structures Using Python>,地址为:http://interactivepython.org/runestone/static/pythonds/index.html是英文的,写的不错,里面代码的实现也很详细,很多有趣的例子,于