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)

 

 

 

 

返回目录

 

posted @ 2019-12-05 20:19  初级电路与软件研究  阅读(437)  评论(0编辑  收藏  举报