• 常用数据结构


    要点概论

    1. 数组(python中用列表代替)

    2. 栈和队列

    3. 集合

    4. 字典

    5.collections 数据结构简介

    1. 数组

      1.1 列表和数组

        python 语言中没有直接提供数组数据类型,通常使用列表作为数组。列表支持数组要求的 4 中核心操作:创建数组,索引访问,索引赋值,迭代遍历。

    示例:生成一副扑克牌(大小王除外),并且随机洗牌后输出一副扑克牌。

    import random
    
    SUITS = ['Club','Diamind','Heart','Spade']   # 梅花,方块,红桃,黑桃
    RANKS = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
    
    deck = []  # 一副扑克牌
    for rank in RANKS:
        for suit in SUITS:
            card = rank + ' of ' + suit
            deck += [card]
    # 洗牌
    n = len(deck)
    for i in range(n):
        r = random.randrange(i,n)
        temp = deck[r]
        deck[r] = deck[i]
        deck[i] = temp
    # 输出一副扑克牌
    for s in deck:
        print(s)
        
    # 程序部分运行结果如下(结果每次随机):
    # 10 of Spade
    # 4 of Diamind
    # 3 of Heart
    # 5 of Spade
    # 5 of Heart
    # Q of Heart
    # 6 of Diamind
    # .....
    deck.py

      1.2 array.array 对象和数组

        array 模块包含一个array 对象,用于实现其他编程语言中的数组数据结构。

        array 对象是包含相同基本数据类型的列表,其操作与 list 对象基本一致,区别是创建 array 对象时,必须指定其元素累心 typecode ,且其元素只能为该类型,否则会导致 TypeError。

        array 对象构造函数为:

    array(typecode[,initializer])

        其中, typecode 为 array 对象中数据元素的类型; initializer 为初始化数据系列或可迭代对象,其元素类型必须与 typecode 一致。

    array.array 对象和数组示例:

    import array
    
    a = array.array('b',(1,2,3,4,5))
    
    print(a[1])    # 2
    a[1] = 22
    print(a[1:])    # array('b', [22, 3, 4, 5])
    
    a[0] = 'abc'    # TypeError: an integer is required (got type str)
    array.array 对象和数组示例

    2. 栈和队列

      2.1 栈的实现:使用列表

        向列表最后位置添加元素和移除元素非常高校和方便,故使用 list ,可以快捷高效地实现栈。 append() 和 pop() 分别对应入栈和出栈操作。

        列表可以实现队列,但并不适合。因为从列表的头部移除一个元素,列表中的所有元素读需要移动位置,所以效率不高。

        可以使用 collections 模块中的 deque 对象。

    栈的实现示例【创建一个包含整数 1 和 2 的栈,展示入栈和出栈操作,以及打印栈的内容】:

    class Stack:
        def __init__(self,size = 16):   #初始化栈
            self.stack = []
        def push(self,obj):
            self.stack.append(obj)
        def pop(self):
            try:
                return self.stack.pop()
            except IndexError as e:
                print('stack is empty')
        def __str__(self):
            return str(self.stack)
    
    stack = Stack()     # 创建并初始化栈
    stack.push(1)       # 整数 1 入栈
    stack.push(2)       # 整数 2 入栈
    print(stack)        #打印栈的内容
    stack.pop()         # 整数 2 出栈
    stack.pop()         # 整数 1 出栈
    stack.pop()         # 出栈操作,但因为是空栈,提示 'stack is empty'
    
    # 程序运行结果如下:
    # [1, 2]
    # stack is empty
    stack.py

      

      2.2 deque 对象

        colletions.deque (双端队列)支持从任意一端增加和删除元素。

        deque 是线程安全,内存高校的队列,它被设计为从两端追加和弹出都非常快。

        构造函数如下:

    deque([iterable[,maxlen]])    # 构造函数

        其中,可选的 iterable 为初始元素;maxlen 用于指定队列长度(默认无限制)。

    deque 对象 dq 支持的方法如下表所示:

    方法 说明
    dq.append(x) 在右端添加元素 x
    dq.appendleft(x) 在左端添加元素 x
    dq.pop() 从右端弹出元素。没有则抛出 IndexError
    dq.popleft() 从左端弹出元素。没有则抛出 IndexError
    dq.extend(iterable) 在右端添加系列 iterable 中的元素
    dq.extendleft(iterable) 在左端添加系列 iterable 中的元素
    dq.remove(value) 移除第一个找到的 x ,没有则抛出 IndexError
    dq.count() 返回元素 x 在队列中出现的个数
    dq.clear() 删除所有元素,即清空队列
    dq.reverse() 反转队列中所有元素
    dq.rotate(n) 如果 n > 0 ,所有元素向右移动 n 个位置(循环);否则向左

    deque 对象示例【读取文件,返回文件的最后 n 行内容】:

    import collections
    
    def tail(filename,n = 10):
        with open(filename) as f:
            return collections.deque(f,n)
    
    path = r'deque_tail.py'
    dq = tail(path,n = 2)
    print(dq.popleft())
    print(dq.popleft())
    
    # 程序运行结果如下:
    # print(dq.popleft())
    #
    # print(dq.popleft())
    deque_tail.py

        

        2.3 deque 作为栈和队列

          deque 对象方法 append() 用于入栈操作;pop() 方法对应于出栈操作。

          deque 对象方法 append() 用于进队操作;popleft() 方法对应于出队操作。

    deque 作为栈示例:

    from collections import *
    
    dq = deque()
    dq.append(1);dq.append(2);dq.append(3)   # 整数 1,2,3 入栈
    dq.pop();dq.pop();dq.pop()               # 整数 3,2,1 出栈
    栈的示例

    deque 作为队列示例:

    from collections import *
    
    dq = deque()
    dq.append(1);dq.append(2);dq.append(3)   # 整数 1,2,3 入队
    dq.popleft();dq.popleft();dq.popleft()               # 整数 3,2,1 出队
    队的示例

     deque作为双向队列:

    from collections import deque
    dq = deque(range(10),maxlen=10)
    print(dq)
    dq.rotate(3)
    # 队列的旋转操作接受一个参数 n ,当 n > 0 时,队列最右边的 n 个元素会被移动到队列的左边;
    # 当n < 0 时,队列最左边的 n 个元素会被移动到右边。
    print(dq)
    
    dq.appendleft(-1)
    # 当试图对一个已满(len(d) == d.maxlen)的队列做头部添加操作的时候,
    # 它尾部的元素会被删除掉。注意在下一行里,元素 6 被删除了。
    print(dq)
    
    dq.extend([11,22,33])
    # 在尾部添加三个元素的操作会挤掉 1-,7,8。
    print(dq)
    
    dq.extendleft([99,88,77])
    # extendleft(iter) 方法会把迭代器里的元素逐个添加到双向队列的左边,
    # 因此迭代器里的元素会逆序出现在队列中。
    print(dq)
    
    # 程序运行结果如下:
    # deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
    # deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10)
    # deque([-1, 7, 8, 9, 0, 1, 2, 3, 4, 5], maxlen=10)
    # deque([9, 0, 1, 2, 3, 4, 5, 11, 22, 33], maxlen=10)
    # deque([77, 88, 99, 9, 0, 1, 2, 3, 4, 5], maxlen=10)
    双向队列

      双向队列除了实现大部分列表所拥有的放啊,也有一些额外的符合自身设计的方法。

      但是为了实现这些方法,双向队列也付出了一些代价,

      从队列中间删除元素的操作会慢一些,因为它只对在头尾的操作进行了优化。

      append 和 popleft 都是原子操作,也就是说 deque 可以在多线程程序中安全地当左先进先出的队列使用,

      而使用者不需要担心资源所 的问题。

      除了 deque 之外,还有其他的 python 标准库也有对队列的实现:http://www.cnblogs.com/HZY258/p/8562078.html

    3. 集合

      集合数据类型是没有顺序的简单对象的聚集,且集合中元素不重复。python 集合数据类型包括可变集合对象(set)和不可变集合对象(frozenset)。

      

      3.1 集合的运算:并集,交集,差集和对称差集

    集合运算如下表所示:

    运算符 说明
    s1|s2 ... 返回 s1,s2,...的并集
    s1&s2& ... 返回 s1,s2,...的交集
    s1-s2 返回 s1,s2,...的差集
    s1^s2 返回 s1,s2, ...的对称差集

    集合的对象方法如下表所示:

    方法 说明
    s1.isdisjoint(s2) 如果集合 s1 和 s2 没有共同元素,返回 True ,否则返回 False
    s1.issubset(s2) 如果集合 s1 是 s2 的子集,返回 True,否则返回 False
    s1.issuperset(s2) 如果集合 s1 是 s2 的超集,返回 True,否则返回 False
    s1.union(s2, ...) 返回 s1,s2,...的并集
    s1.intersection(s2,...) 返回 s1,s2,...的交集
    s1.difference(s2,...) 返回 s1,s2,...的差集
    s1.symmetric_difference(s2) 返回 s1 和 s2 的对称差集

      

      3.2 集合的比较运算;相等,子集和超集

    集合支持如下表所示的比较运算:

    运算符 说明 运算符 说明
     s1 = s2 s1和 s2的元素相同 s1 <= s2 s1是 s2的子集
    s1 != s2 s1和 s2的元素不完全相同 s1 >= s2 s1是 s2的超集
    s1 < s2 s1是 s2的纯子集 s1 > s2 s1是 s2的纯超集

      

     

     

     

     

      3.3 集合的长度,最大值,最小值,元素和

        通过内置函数 len(), max(), min(), sum(),可以获取集合的长度,元素最小值,元素最小值,元素之和。

        如果元素有非整数,则求和将导致 TypeError 异常。

    4. 字典(映射)

      字典(dict , 或映射 map)是一组键/值队的数据结构。每个键对应于一个值。在字典中,键不能重复。根据键可以查询到值。

      

      4.1 对象的哈希值

        字典是键和值的映射关系。字典的键必须是可 hash 的对象,即实现了 __hash__() 的对象,

        一个对象的 hash 值也可以使用内置函数 hash() 获得。

        不可变对象是可 hash 对象;而可变对象通常是不可 hash 对象,因为不可变对象的内容可以改变,因而无法通过 hash() 函数获取其 hash 值。

        字典的键只能使用不可变的对象,但字典的值可以使用不可变或可变的对象。一般而言,应该使用简单的对象作为键。

      

      4.2 字典的视图对象

        字典 d 支持下列的视图对象,通过它们,可以动态访问字典中的数据。

          d.key()      # 返回字典 d 的键 key 的列表

          d.values()      # 返回字典 d 的值 value 的列表

          d.items()     # 返回字典 d 的键值(key ,value)队的列表

      4.3 字典对象的长度和比较

        通过内置函数 len(),可以获取字典的长度(元素个数)。

        虽然字典对象也支持内置函数 max() ,min() ,sum(),以计算字典 key,但没有太大意义。

        另外,字典对象也支持比较运算符(< ,<= ,== ,!= ,>= ,>),但只有 == ,!= 有意义。

    5.collections 数据结构简介

    http://www.cnblogs.com/HZY258/p/8537812.html

      

  • 相关阅读:
    转发:原本优秀的我们是怎样滑向平庸的
    阿里巴巴C++实习生相关招聘一则
    [置顶] 我希望在20岁时就知道的26条时间管理技巧
    提示用户进行版本更新并且发布通知监控版本下载情况
    树状数组求正序数与逆序数hdu Minimum Inversion Number
    通过js 实现简单验证码的 刷新 看不清 换一张
    配置 CACTI 监控 MySQL 数据库状态
    Win7下ADB不能识别设备的可能原因
    Java 开源博客——B3log Solo 0.6.0 正式版发布了!
    MyEclipse下Import没有Maven的处理办法
  • 原文地址:https://www.cnblogs.com/HZY258/p/8522906.html
Copyright © 2020-2023  润新知