内置序列类型概览
在《算法》一书中,数组,链表称为数据结构
.
包
,队列
,栈
称为数据类型,在《流畅的python》第二章中,首先介绍了python几种内置(即不用程序员实现,python自带)的序列类型:
《流畅的python》中列图示了可变和不可变序列的差异,在我看来,可变数据多了一些可以操作数据的方法,增删,修改值等.list列表是最基础的可变序列,类似C语言的数组,只是它更灵活一些,它是容器序列,存放的元素数据类型可以是不一样的.
列表推导和生成器表达式
列表可以用列表推导
这种方法来快速构造一个列表,而生成器表达式
可以创建其它任何类型的序列.
symbols = '!@#$%^^&*()_+'
codes = [ord(symbol) for symbol in symbols]
print(codes)
ord(parm)将parm转换成数值,这个数值是它对应的的Unicode码位,这里参数是一个字符,所以转换后是一个列表,user_list = [func() for n in N]
这是一个列表生成器,它方便的生成一个列表.第一章初有涉及.其中列表中的 n 是一个局部变量,所以不用担心修改到其他变量.详细见《流畅的python》 2.2.1
如果把列表推导的[]
改为 ()
,则列表推导变为生成器表达式
:
tuple(ord(symbol) for symbol in symbols)
用法类似,区别在于,列表推导会建立一个完整的列表,而生成器会一个一个产出,程序可以逐个操作它们.我能想到的用法是,对于一个列表,生成到某一个值以后,程序就不需要继续生成了,那么生成器表达式是更好的.但是我并没有通过代码验证.
colors = ['black','white']
sizes = ['S','M','L']
for tshirt in ('%s %s'%(c ,s) for c in colors for s in sizes):
print(tshirt)
这是书的源程序(实例2-6),它的输出为:
black S
black M
black L
white S
white M
white L
我做了一个小练习,加入一行判断的代码,让其打印出white S
后就不再输出:
colors = ['black','white']
sizes = ['S','M','L']
for tshirt in ('%s %s'%(c ,s) for c in colors for s in sizes):
print(tshirt[:5],tshirt[-1])
if tshirt[:5] == 'white' and tshirt[-1] == 'S':
break
它的输出为:
black S
black M
black L
white S
可以看到,少打印的最后两行,for
循环下print(tshirt[:5],tshirt[-1])
无法用c
,s
来表示,只能用tshirt
,我想是前文作用域的原因,如果你不理解中括号里面的:5
和-1
,请查看python列表相关的内容.
元祖不仅仅是不可变的列表 这小节指出:元组不只是存放一个值,还存放了这个值的位置,.2.25小节有具体的对比,不过我依旧没有看出来元组和不可以被改变的列表有什么不同…
具名元组
指的是元素拥有名字,即是可以给元组里面各个元素命名,然后通过其名字来访问它
from collections import namedtuple
City = namedtuple('City','name country population coordinates')
tokyo = City('Tokyo','JP',36.993,(35.689722,139.691667))
print(tokyo)
print(tokyo.name)
它的输出:
City(name='Tokyo', country='JP', population=36.993, coordinates=(35.689722, 139.691667))
Tokyo
City = namedtuple('City','name country population coordinates')
看起来有点奇怪,它的第二个参数不是第一章那样的元组,而是字符串,测试效果来看,使用字符串也是可以的,只要一一对于即可,书中指明:“后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串.”print(tokyo.name)
通过名字来访问数组的元素,这样比通过位置来访问更具可读性
此外,还可以使用 namedtuple._asdict()
格式化输出具名元组:
from collections import namedtuple
City = namedtuple('City','name country population coordinates')
tokyo = City('Tokyo','JP',36.993,(35.689722,139.691667))
print(tokyo._asdict())
它的输出:
{'name': 'Tokyo', 'country': 'JP', 'population': 36.993, 'coordinates': (35.689722, 139.691667)}
切片
一个长度为N(N>x)的列表,user_list[:x]
,```user_list[x:]``,第一个是[0,x),第二个是[x,N-1],这就是切片和区间会忽略最后一个元素的原因.
序列的增量赋值
l = [1,2,3] #一个列表 l
t = (1,2,3) #一个元组 t
l *= 2 #每一个元素都乘2
t *= 2 #每一个元素都乘2
print(l,t)
它的输出:
[1, 2, 3, 1, 2, 3] (1, 2, 3, 1, 2, 3)
在这段程序中,每个序列都被扩展了,但是如果你使用id()
来观察它们各自的位置信息,可以发现,列表的首地址没有改变,但是元组的首地址已经改变了.所以对元组的操作会更加消耗时间.本小节还提到了列表 +=
的谜题,在平时中避免使用即可.
list.sort方法和内置函数sorted
list.sort
和list.sorted
都是排序列表(默认小在前,大在后,reverse 参数可以改为 True,这样就会反过来排序),区别在于,sort()
是原地排序,使用这个方法后,list
列表的值会改变,它会放回None,而sorted()
则在不改变原来列表的情况下,新建预一个排序后的列表,可以使用python的列表推导来生成一个随机的列表,并测试他们的排序,sorted()
可自行实现:
import random
l = [random.randint(0,100) for i in range(20)] #在0-99之间生成20个随机数,存放在 l 中
print("初始值",l)
l.sort()
print("排序后",l)
输出:
初始值 [25, 39, 35, 8, 37, 60, 43, 44, 84, 48, 73, 11, 47, 46, 26, 66, 85, 58, 68, 74]
排序后 [8, 11, 25, 26, 35, 37, 39, 43, 44, 46, 47, 48, 58, 60, 66, 68, 73, 74, 84, 85]
当列表不是首选时
列表比较灵活,但是如果数值是统一的,直接使用数组会更加的高效,如果需要频繁的对队列先进先出处理,qeque则更加合适,所以程序员可以了解各种数据结构的优缺点,在设计程序的时候可以做到更优.array.array
元素只能是数字,没有列表灵活但是更加的高效,包含.pop()
,.insert
,.exted
,以及操作文件的.frombytes()
,.tofile
.pickle
模块的pickle.dump()
方法接近array.tofile()
,不过他可以处理几乎所有的内置数据类型.在Python 3.4版本,数组类型就不支持就地排序了,需要新建立一个数组来存放排序后的值.
numbers = array.array('h',[-2,-1,0,1,2]) #创建一个数组
这里数组又2个参数,第一个h
表示用 int 类型创建数组:
Code | C Type | Python Type | Min bytes |
b | signed char | int | 1 |
B | unsigned char | int | 1 |
u | Py_UNICODE | Unicode | 2 |
h | signed | short int | 2 |
H | unsigned short | int | 2 |
i | signed int | int | 2 |
I | unsigned int | int | 2 |
l | signed long | int | 4 |
L | unsigned long | int | 4 |
f | float | float | 4 |
d | double | float | 8 |
表格参考:Python Array
矩阵的计算,建议使用 NumPy和SciPy库.注意,这2个库都是第三方库,所以你在使用以下代码,需要确保已经安装了Numpy库.
imoprt numpy
如果使用list来做队列是可以的,但是collections.deque
这个类更加的合适,可以理解这个类是针对队列设计的.‘‘collections.deque 类(双向队列)是一个线程安全、可以快速从两端添加或者删除元素的数据类型。’’