• python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列


    版权声明:本文为博主原创文章。未经博主同意不得转载。 https://blog.csdn.net/signjing/article/details/36201499

    标准库:一些最爱

    集合、堆和双端队列

    集合

    集合Set类位于sets模块中。

    >>> range(10)

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

    >>> set(range(10))

    set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

     

    集合是由序列(或其它可迭代的对象)构建的。主要用于检查成员资格。因此,副本是被忽略的:

    >>> range(10)*2

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

    >>> set(range(10)*2)

    set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

     

    和字典一样,集合元素的顺序是随意的,因此不应该以元素的顺序作为根据进行编程:

    >>> set(['b','a','c'])

    set(['a', 'c', 'b'])

     

    除了检查成员资格外,还能够使用标准的集合操作。如求并集和交集,能够用法,也能够对整数进行位操作时使用的操作。

    如想找出两个集合的并集。能够使用其中一个集合的union方法或者使用按位与(OR)运算符”|”:

    >>> a=set(range(5))

    >>> a

    set([0, 1, 2, 3, 4])

    >>> b=set(range(1,8,2))

    >>> b

    set([1, 3, 5, 7])

    >>> a.union(b)

    set([0, 1, 2, 3, 4, 5, 7])

    >>> a|b

    set([0, 1, 2, 3, 4, 5, 7])

     

    其它方法和运算符

    交集

    >>> c=a&b

    >>> c

    set([1, 3])

    >>> c.issubset(a)

    True

    >>> c.issubset(b)

    True

    >>> c<=a

    True

    >>> c>=a

    False

    >>> c<=b

    True

    >>> c>=b

    False

    >>> a.intersection(b)

    set([1, 3])

    >>> a&b

    set([1, 3])

     

    >>> a.difference(b)

    set([0, 2, 4])

    >>> a-b

    set([0, 2, 4])

    >>> b-a

    set([5, 7])

    >>> b.difference(a)

    set([5, 7])

     

    对称差

    >>> a.symmetric_difference(b)

    set([0, 2, 4, 5, 7])

    >>> a^b

    set([0, 2, 4, 5, 7])

     

    拷贝

    >>> a.copy()

    set([0, 1, 2, 3, 4])

    >>> a.copy() is a

    False

     

    还有些原地运算符和相应的方法,以及基本方法addremove

     

    集合是可变的,所以不能用做字典中的键。

    另外一个问题是集合本身仅仅能包括不可变(可散列的)值,所以也就不能包括其它集合。

    实际其中。集合的集合是非经常常使用的。所以这就是个问题:

    幸好有个frozenset类型,用于代表不可变(可散列)的集合:

    >>> a=set()

    >>> b=set()

    >>> a.add(b)

     

    Traceback (most recent call last):

      File "<pyshell#33>", line 1, in <module>

        a.add(b)

    TypeError: unhashable type: 'set'

    >>> a.add(frozenset(b))

     

    Frozenset构造函数创建给定集合的副本,无论是集合作为其它集合还是字典的键,frozenset都非常实用。

    堆(heap)是优先队列的一种。使用优先队列能够以随意顺序添加对象,而且能在不论什么时间(可能在添加对象的同一时候)找到(也可能是移除)最小的元素,也就是说比用于列表的min方法要有效率得多。

     

    其实,python并没有独立的堆类型——仅仅有一个包括一些堆操作函数的模块,这个模块叫做heapqqqueue的缩写)。

     

    Heapq模块中重要的函数

     

    函数

    描写叙述

    heappush(heap,x)

    x入堆

    heappop(heap,x)

    将堆中最小的元素弹出

    heapify(heap)

    heap属性强制应用到随意一个列表

    heapreplace(heap,x)

    将堆中最小的元素弹出,同一时候将x入堆

    nlargest(n,iter)

    返回iter中第n大的元素

    nsmallest(n,iter)

    返回iter中第n小的元素

     

    heappush函数用于添加堆的项。注意,不能将它用于不论什么之前讲述的列表中——它仅仅能用于通过各种堆函数创建的列表中。

    原因是元素的顺序非常重要。

     

    >>> from heapq import *

    >>> from random import shuffle

    >>> data=range(10)

    >>> shuffle(data)

    >>> heap=[]

    >>> for n in data:

    heappush(heap,n)

     

    >>> heap

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

    >>> heappush(heap,0.5)

    >>> heap

    [0, 0.5, 5, 3, 1, 6, 7, 9, 8, 4, 2]

     

    元素的顺序并不像看起来那么随意。虽然不是严格排序的,但也是有规则的:位于i位置上的元素总比i/2位置处的元素大(反过来说就是i位置处的元素总比2*i以及2*i+1位置处的元素小)。这是底层堆算法的基础,而这个特性称为堆属性

     

    heappop函数弹出最小的元素——一般来说都是在索引0处的元素,而且会确保剩余元素中最小的那个占领这个位置(保持刚才提到的堆属性)。

    一般来说。虽然弹出列表的第一个元素并非非常有效率,但在这里不是问题。由于heappop在“幕后”会做一些静止的移位操作:

    >>> heappop(heap)

    0

    >>> heappop(heap)

    0.5

    >>> heappop(heap)

    1

    >>> heap

    [2, 3, 5, 8, 4, 6, 7, 9]

     

    heapify函数使随意列表作为參数。并通过尽可能少的移位操作,将其转换为合法的堆。假设没实用heappush建立堆,那么在使用heappushheappop前应该使用这个函数。

    >>> heap=[5,8,0,3,6,7,9,1,4,2]

    >>> heap

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

    >>> heapify(heap)

    >>> heap

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

     

    heapreplace函数并不像其它函数那么经常使用。它弹出堆的最小元素。而且将新元素推入,这样做比调用heappop之后再调用heappush更高效。

    >>> heapreplace(heap,0.5)

    0

    >>> heap

    [0.5, 1, 5, 3, 2, 7, 9, 8, 4, 6]

    >>> heapreplace(heap,10)

    0.5

    >>> heap

    [1, 2, 5, 3, 6, 7, 9, 8, 4, 10]

     

    heapq模块中剩下的两个函数nlargest(n,iter)nsmallest(n,iter)分别用来寻找不论什么可迭代对象iter中第n大或第n小的元素。能够使用排序和分片来完毕这个工作。但堆算法更快而且更有效地使用内存。也更易用。

    双端队列

    双端队列(Double-ended queue,或称deque在须要依照元素添加的顺序来移除元素时非常实用。

    双端队列通过可迭代对象(比方集合)创建,而且有些非常实用的方法。

    >>> from collections import deque

    >>> q=deque(range(5))

    >>> q.append(5)

    >>> q.appendleft(6)

    >>> q

    deque([6, 0, 1, 2, 3, 4, 5])

    >>> q.pop()

    5

    >>> q.popleft()

    6

    >>> q

    deque([0, 1, 2, 3, 4])

    >>> q.rotate(-1)

    >>> q

    deque([1, 2, 3, 4, 0])

    >>> q.rotate(3)

    >>> q

    deque([3, 4, 0, 1, 2])

     

    双端队列好用的原因是它能够有效地在开头(左側)添加和弹出元素,这是列表中无法实现的

    除此之外。使用双端队列的优点还有:能够有效地旋转(rotate)元素(也就是将它们左移或右移,使头尾相连)。双端队列对象还有extendextendleft方法。extend和列表的extend方法几乎相同。extendleft则相似于appendleft。注意,extendleft使用的可迭代对象中的元素会反序出如今双端队列中。

  • 相关阅读:
    mysql练习题
    转 -day19--form&modelform
    day20--注册功能及首页
    day19-form表单&auth模块、项目初识
    day15-pymysql模块的使用
    第14天jquery+bootstrap
    第13天-js+jquery
    iTween基础之Punch(摇晃)
    iTween基础之Audio(音量和音调的变化)
    iTween基础之Rotate(旋转角度)
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10684510.html
  • Copyright © 2020-2023  润新知