• Python语法速查: 15. 常用数据结构


    返回目录

    本篇索引

    (1)array

    (2)bisect

    (3)deque

    (4)defaultdict

    (5)namedtuple

    (6)heapq

    (7)itertools

     (1)array

    array模块定义一个数组类型:array,它与列表很相似,但它的内容仅限于单一类型。如果需要有效利用存储空间,那么就需要用到array模块。 例如,要存储1000万个整数,使用列表需要约160M内存,而使用array仅需40M内存,代价是array的操作比列表要慢一些。

    array数组不适用于数字操作(如矩阵运算),要创建高效存储和计算的数组,可使用numpy扩展。

    “+”运算符用于附加另一个数组的内容,“*”运算符用于重复附加一个数组。

    ● array(typecode [,initializer])

    说明:

    创建类型为typecode的数组,可取类型见下表。initializer是一个字符串或值列表,用于初始化数组中的值。

    typecode取值类型

    类型编码描述对应C类型最小大小(字节数)
    'c' 8位字符 Char 1
    'b' 8位整型 signed char 1
    'B' 8位无符号整型 unsigned char 1
    'u' Unicode字符 PY_UNICODE 2或4
    ''h 16位整型 short 2
    'H' 16位无符号整型 unsigned short 2
    'i' 整型 int 4或8(64位架构)
    'I' 无符号整型 unsigned int 4或8(64位架构)
    'l' 长整型 long 4或8(64位架构)
    'L' 无符号长整型 unsigned long 4或8(64位架构)
    'f' 单精度浮点数 float 4
    'd' 双精度浮点数 double 8

    array实例常用属性和方法

    属性或方法说明
    a.typecode 属性,数组的编码字符。
    a.itemsize 属性,存储在数组中项的大小(以字节为单位)。
    a.append(x) 将x附加到数组末尾,若插入类型不匹配,则引发TypeError异常。
    a.buffer_info() 返回(address, length)元组,反映数组缓冲区的内存位置和长度。
    a.byteswap() 切换大端和小端的字节顺序,仅支持整型值。
    a.count(x) 返回数组中出现x的次数。
    a.extend(b) 将b附加到数组末尾,b也可以是一个数组。
    a.fromfile(f, n) 从文件对象f中读取n个项(二进制格式),并附加到数组末尾。若可读取的项少于n,则引发EOFError异常。
    a.fromlist(list) 将list中的项附加到数组末尾,list可以是可迭代对象。
    a.fromstring(s) 将字符串s中的项附加到数组末尾,其中s是一个由二进制值组成的字符串(与fromfile()中格式相同)
    a.index(x) 返回x在数组中首次出现的位置索引,若未找到,则引发ValueError异常。
    a.insert(i, x) 在位置i前插入x。
    a.pop([i]) 从数组中删除项 i 并将其返回。如果i已被删除,则删除最后一个元素。
    a.remove(x) 从数组中删除第一个x,若未找到,则引发ValueError异常。
    a.reverse() 反转数组的顺序。
    a.tofile(f) 将所有项写入文件f。数据保存为本机二进制格式。
    a.tolist() 将数组转换为普通的值列表。
    a.tostring() 将数组转换为由二进制数据组成的字符串。
    a.tounicode() 将数组转换为Unicode字符串,如果数组类型不为'u',则引发ValueError异常。

     (2)bisect

    bisect模块可以在已排好顺序的列表中插入一个新数据,并使列表维持已排好的顺序,它使用二分法来执行大部分工作。

    bisect的简单用例:

    s = [1,3,5,7,9]
    bisect.insort(s, 6)     
    print(s)
    
    # 结果为:[1,3,5,6,7,9]

    bisect模块常用函数

    属性或方法说明
    insort(list, item [,low [,high]]) 将item插入已排序好的列表list中。若item已在列表中,那么新项将插到现有项的右边。low和high是两边的要检查子集的边界。
    insort_left(list, item [,low [,high]]) 功能同上,只是若item已在列表中,那么新项将插到现有项的左边。
    insort_right(list, item [,low [,high]]) 同insort()
    bisect(list, item [,low [,high]]) 计算如要将item插入到已排序好的的列表list中的插入索引点,并返回这个值。low和high是两边的要检查子集的边界。若item已在列表中,那么新计算的插入位置在现有项的右边。
    bisect_left(list, item [,low [,high]]) 功能同上,只是若item已在列表中,那么新计算的插入位置在现有项的左边。
    bisect_right(list, item [,low [,high]]) 同bisect()

     (3)deque

    deque表示双端队列(发音:'deck'),要使用双端队列需要导入collections模块。

    双端队列允许在队列的任一端插入或删除项,性能接近O(1)。而列表若要在最前端插入项,需要移动所有后续对象。

    若为deque指定了maxlen参数,则向已满双端队列插入新项时,deque会自动在另一端删除一个数据来腾出空间。

    ● deque[iterable [,maxlen]])

    说明:

    iterable是可迭代对象,可用于初始化deque;maxlen表示双端队列允许的最大空间。

    deque实例常用方法

    属性或方法说明
    d.append(x) 将x添加到d的右端。
    d.appendleft(x) 将x添加到d的左端。
    d.clear() 从d中删除所有项。
    d.extend(iterable) 将iterable中的所有项添加到d的右端,以扩展d。
    d.extendleft(iterable) 将iterable中的所有项添加到d的左端,iterable中的项将按相反顺序出现在d中。
    d.pop() 返回并删除d右端的项。若d为空,则引发IndexError异常。
    d.popleft() 返回并删除d左端的项。若d为空,则引发IndexError异常。
    d.remove(item) 删除首次出现的item,若未找到匹配值,则引发ValueError异常。
    d.rotate(n) 将所有项向右旋转n步,若n为负值,则向左旋转项。

    另外,deque实例也支持以下内置操作或内置函数:迭代、in操作符、 []下标操作、len(d)reversed(d)copy.copy(d)copy.deepcopy(d)

    对于下标操作,在头尾处的取出速度为 O(1),在队列中间处的取出速度退化为O(n)。

    从Python3.5起,还支持__add__()__mul()____imul()__方法。

     (4)defaultdict

    要使用defaultdict需要导入collections模块。defaultdict与普通字典用法基本一样,只是在缺少键的处理上有不同。当索引不存在的键名时,将调用default_factory提供的函数来提供一个默认值,然后将该值保存为键的值。其余操作与内置dict()完全相同。

    其实,普通的字典的setdefault()方法也能完成这一功能,只是setdefault()语句结构不是很清晰,且运行速度较慢。

    初始化语法:

    default([default_factory], ...)

    用法示例,统计各个单词出现的位置并将其位置序列放入字典中。

    from collections import defaultdict
    s = 'a b c a b c'
    word_list = s.split()   # word_list值为:['a', 'b', 'c', 'a', 'b', 'c']
    dd = defaultdict(list)
    for i, w in enumerate(word_list):
        dd[w].append(i)
        
    # 最终dd结果为:defaultdict(<class 'list'>, {'a': [0, 3], 'b': [1, 4], 'c': [2, 5]})

     (5)namedtuple

    namedtuple表示命名元组,要使用namedtuple需要导入collections模块。在命名元组中,可以使用属性名称来访问元组元素,可以动态增加新属性。缺点是比普通元组慢一点。

    初始化语法:

    namedtyple(typename, filednames [,verbose])

    typename作为新创建的命名元组名称(它是tuple的子类),fieldnames是字符串形式的属性名称的列表,不能以下划线开头。fieldnames也可写成一个字符串,各属性间用空格或逗号分隔。verbose标记若设为True,将向标准输出端输出生成的类定义。

    使用命名元组的简单示例:

    from collections import namedtuple
    NewAddrPort = namedtuple('NewAddrPort', ['ipaddr', 'port'])
    a = NewAddrPort('127.0.0.1', 80)
    print(a.ipaddr, a.port)
    # 结果为:'127.0.0.1' 80
    
    ipaddr, host = a      # 本句可将命名元组a像普通元组那样解包展开。
    
    isinstance(a, tuple)
    # 结果为:True

    如果定义一个仅作为数据结构的对象,那可以用命名元组来替代:

    class Square(object):
        def __init(self, l, w):
            self.l = l
            self.w = w
    
    # 可以用命名元组来替代:
    import collections
    Square = collections.namedtuple('Square', 'l w')
    nt = Square(10, 20)

    使用命名元组的优点是:可以像实例那样来访问属性,如:nt.l、nt.w;也可以对nt像普通元组那样使用for语句和解包语句。

     (6)heapq

    heapq模块使用堆实现一个优先级队列。优先级队列能以任意顺序添加对象,并能随时找出最小的元素,它比列表的min方法要快得多。

    heapq模块常用函数

    函数说明
    heapify(x) 将列表x原地转换为堆。
    heappop(heap) 返回并删除heap中最小的项,若heap为空,则引发IndexError异常。
    heappush(heap, item) 将item添加到堆中。
    heappushpop(heap, item) 在一个操作中将item添加到堆并从heap中删除最小项。这比分别调用heappush()和heappop()更高效。
    heapreplace(heap, item) 返回并删除堆中最小的元素,并同时添加一个新item。新项的添加在获取返回值之后,因此返回值可能比item更大。若heap为空,则引发IndexError异常。
    merge(s1, s2, ...) 创建一个迭代器,将有序的迭代变量s1, s2等合并到一个有序序列中。
    nlargest(n, iter [,key]) 创建一个列表,包含iter中最大的n个项,最大项排在返回列表的前端。key是可选参数,接受一个输出参数并计算iter中每个项的比较键。
    nsmallest(n, iter [,key]) 创建一个列表,包含iter中最小的n个项,最小项排在返回列表的前端。key含义同上。

    heap用法示例:

    import heapq
    x = [1,9,2,8,3,7,4,6]
    heapq.heapify(x)    # 本句运行后,x已变成优先级队列
    print(x)
    >>> [1,3,2,6,8,7,4,9]   # x已按堆的优先级排序好
    heapq.heappop(x)
    >>> 1
    heapq.heappop(x)
    >>> 2

     (7)itertools

    itertools模块包含创建高效迭代器的函数,可以用各种方式对数据执行循环操作。

    itertools模块常用函数

    函数说明
    chain(iter1, iter2, ..., iterN) 此函数创建一个新迭代器将所有入参迭代器链接起来,返回的迭代器从iter1的第1项开始,到iterN的最后一项。
    chain.from_iterable(iterables) 一个备用链构造函数。
    combinations(iter, r) 创建一个迭代器,返回iter中所有长度为r的子序列。例如:combinations([1,2,3], 2)生成的序列为:[1,2]、[1,3]、[2,3]。
    count([n]) 创建一个迭代器,生成从n开始的连续整数,如果忽略n则从0开始。如果超出了系统的最大正整数范围,则从系统最小负整数-1继续。
    cycle(iter) 创建一个迭代器,对iter中的元素反复执行循环操作,生成一个迭代器副本。
    dropwhile(predicate, iter) 创建一个迭代器,只要函数perdicate(item)为True,就丢弃iter中的项,若为False则存入此项到新迭代器。
    filterfalse() 创建一个迭代器,仅生成iter中predicate(item)为False的项,若predicate为None,将返回iter中所有计算为False的项。
    groupby(iter, [,key]) 创建一个迭代器,对iterable生成的连续项进行分组,在分组过程中会查找重复项。
    islice(iter [,start], stop [,step]) 创建一个迭代器,生成的项类似于切片返回值:iter[start:stop:step],但start, stop, step都不能使用负值。
    permutations(iter [,r]) 创建一个迭代器,返回iter中所有长度为r的序列,若省略r,那么序列长度与iter中的项数相同。
    product(iter1, iter2, ..., iterN, [repeat=1]) 创建一个迭代器,生成表示item1, item2等中的项的笛卡尔积的元组。repeaet指定重复生成序列的次数。
    repeat(object [,times]) 创建一个迭代器,重复生成object。times指定重复计数,如果未指定times,将无止尽地返回该对象。
    starmap(func [,iter]) 创建一个迭代器,生成值未func(*item),只有当iter生成的项适合用于这种调用函数的方式时,此函数才有效。
    takewhile(predicate [,iter]) 创建一个迭代器,深禅iter中predicate(item)未True的项,只要predicate计算未False,迭代就会立刻停止。
    tee(iter [,n]) 从iter创建n个独立的迭代器,创建的迭代器以n元组的形式返回,n的默认值为2。

    迭代器使用的一些示例:

    from itertools import *
    
    # 在数字0,1,...,10,9,8,...,1上无限循环
    for i in cycle(chain(range(10), range(10,0-1))):
        print(i)
        
    # 创建a中的唯一项列表
    a = [1,2,3,4,2,3,4,5]
    a.sort()
    b = [k for k,g in groupby(a)]   # b = [1,2,3,4,5]
    
    # 对x和y中所有可能的值对进行组合迭代
    x = [1,2,3]
    y = [10,11]
    for r in product(x,y):
        print(r)
    # 生成输出:(1,10), (1,11), (2,10), (2,11), (3,10), (3,11)
    

     

    返回目录

  • 相关阅读:
    Java编程之路相关书籍
    JAVA中的Random()函数
    在鼠标右键上加入使用notepad++编辑
    更改IE浏览器的收藏夹位置
    Java四类八种数据类型
    成为Java顶尖程序员 ,看这11本书就够了
    面向对象(多异常的声明与处理)
    面向对象(异常try-catch)
    面向对象(异常概述)
    面向对象(局部内部类和匿名内部类)
  • 原文地址:https://www.cnblogs.com/initcircuit/p/11975919.html
Copyright © 2020-2023  润新知