Python序列构成的数组
1、内置序列类型
容器序列:list,tuple,collections.deque (能存放不同类型)
扁平序列:str,bytes,bytearray,memoryview,array.array
▲ 容器序列存放的是所包含的任意类型的对象引用。
可变序列:list,bytearray,memoryview,array.array,collection.deque
不可变序列:str,tuple,bytes
2、列表推导式、生成器表达式
2.1、列表推导和生成器表达式
列表推导(listcomps)是构建列表的快捷方式,通常原则是只用列表推导来创建新的列表。
生成器表达式(genexps)用来创建其他类型的序列。
>>> x = 'ABC'
>>> dummy = [ord(x) for x in x]
>>> x
'ABC'
>>> dummy
[65,66,67]
▲ Python3 中的列表推导式、生成器表达式、集合推导、字典推导都有自己的局部作用域。表达式内部的变量和赋值只在局部作用域生效。
列表推导可以帮助我们把一个序列或是其他可迭代类型中的元素进行过滤或是加工,然后再新建一个列表。
2.2、列表推导同 filter 和 map 比较
>>> x = 'ABCDEF'
>>> dummy = [ord(x) for x in x if ord(x)>66]
>>> dummy
[66,67,68,69,70]
>>> dummy = list( filter(lambda c:c>66,map(ord,x)) )
>>> dummy
[66,67,68,69,70]
2.3、生成器表达式
生成器表达式遵守迭代器协议,可以逐个产出元素,而不是先建立一个完整的列表。
▲ 生成器表达式的语法和列表推导差不多,只是把方括号改成圆括号!
colors = ['black','white']
sizes = ['S','M','L']
for tshirt in ('%s %s'%(c,s) for c in colors for s in sizes):
print(tshirt)
3、元组
3.1、元组的拆包
元组除了用作不可变的列表,它还可以用于没有字段名的记录
元组的拆包形式之一(平行赋值)
>>> scores = (93,97)
>>> CN,EN = scores #元组拆包
>>> CN
93
>>> EN
97
不使用中间变量交换元素
>>> a,b = b,a
用 * 运算符把 可迭代对象 拆开作为函数的参数
>>> t = (20,8)
>>> divmod(*t)
(2,4)
让函数用元组的形式返回多个值
>>> import os
>>> _,filename = os.path.split('/home/abc.py')
>>> filename
abc.py
_ 占位符能帮助处理不感兴趣的数据。
用 * 号处理剩下的元素(这个变量可以放在赋值表达式的任意位置)
>>> a,b,*rest = range(5)
>>> a,b,rest
(0,1,[2,3,4]) >>> a,*body,b,c = range(5)
>>> a,*body,b,c
(0,[1,2],3,4)
嵌套元组的拆包
class1 = [
('xiaoming','Boy',(85,88,90)),
('xiaohong','Girl',(90,88,90)),
]
for name,sex,scores in class1:
print(name,sex,scores)
3.2、具名元组
collections.namedtuple 是一个工厂函数,用来创建一个带字段名的元组和一个有名字的类。
创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。
可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串
>>> from collections import namedtuple
>>> City = namedtuple('City','name country population coordinates') # <class '__main__.City'>
>>> tokyo = City('Tokyo','JP',38.32,(35.68872,139.25436))
>>> tokyo
City(name='Tokyo', country='JP', population=38.32, coordinates=(35.68872, 139.25436))
>>> tokyo.population
38.32
>>> tokyo[0]
'Tokyo'
具名元组还具有自己专有属性:_fields类属性,类方法_make(iterable),实例方法_asdict()
>>> City._fields
('name', 'country', 'population', 'coordinates') >>> LatLong = namedtuple('LatLong','lat long')
>>> delhi_data = ('Delhi NCR','IN',32.21,LatLong(28.45721,76.89342))
>>> delhi = City._make(delhi_data) # 生成实例类似 City(*delhi_data) >>> delhi._asdict()
OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population', 32.21), ('coordinates', LatLong(lat=28.45721, long=76.89342))])
4、切片
4.1、切片
在切片和区间操作里不包含区间范围的最后一个元素。这样带来的好处有:
● 当只有一个位置信息时,我们也可以快速看出切片和区间里有几个元素:range(3) 和 my_list[:3] 都返回3个元素。
● 当起止位置都可见时,可以计算出切片和区间的长度(stop - start )
● 利用任意一个下标把序列分割成不重叠的两部分。my_list[:x] 和 my_list[x:]
4.2、对对象进行切片
对 seq[start:stop:step] 进行求值的时候,Python会调用 seq.__getitem__(slice(start,stop,step))
>>> HTML = """ ... 文本内容 """
>>> TEXT_HEAD = slice(0,23)
>>> IMG_URL = slice(23,56)
>>> for item in HTML:
print(item[TEXT_HEAD],item[IMG_URL])
▲ 如果赋值的对象是一个切片,那么赋值语句的右侧必须是个可迭代对象。
>>> li = list(range(10))
>>> li[2:5] = 100
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'range' object does not support item assignment
>>> li[2:5] = [100]
5、对序列使用 + 和 *
+ 号两侧的序列由同类型的数据所构成,在拼接的过程中,两个被操作的序列都不会被修改。
=》 Python会新建一个包含同类型数据的序列来作为拼接的结果。
▲ 在 a * n 语句中,如果序列a里的元素是对其他可变对象的引用,得到的列表里包含的3个元素其实是3个引用。
>>> my_list = [[]] * 3
>>> my_list
[[], [], []]
>>> print(id(my_list[0]),id(my_list[1]),id(my_list[2]))
1767860956104 1767860956104 1767860956104 >>> my_list = [[''] *3 for i in range(3) ]
>>> print(id(my_list[0]),id(my_list[1]),id(my_list[2]))
1767860947400 1767860945992 1767860953544
增量赋值运算符 += 和 *= 利用的特殊方法是 __iadd__ (就地加法)和 __imul__,但是如果没有实现 __iadd__ 和 __imul__ 的话,
a += b 效果就变成了 a = a + b,首先计算 a + b,得到一个新的对象,然后赋值给 a。
可变序列一般都实现了 __iadd__ 和 __imul__
一个罕见的边界情况:
>>> t = (1,2,[3,4])
>>> t[2] += [5,6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t
(1, 2, [3, 4, 5, 6])
▲ 不要把可变对象放在元组里面。
▲ 增量赋值不是一个原子操作。
▲ Python 运行原理可视化分析工具 → http://www.pythontutor.com/visualize.html#mode=edit
6、排序
6.1、list.sort 方法和内置函数 sorted()
list.sort 方法会就地排序列表,返回None值。
sorted() 方法会新建一个列表作为返回值。
list.sort 和 sorted函数,都有两个可选的关键字参数。
reverse :被设定为 True,被排序的列表的元素会以降序输出。
key:一个只有一个参数的函数,这个函数会被用在序列里的每一个元素上,所产生的结果将是排序算法依赖的对比关键字,如key=len
key参数也可以对一个混有数字字符和数值的列表进行排序。
>>> l = [1,7,3,'2','6',8]
>>> sorted(l,key=int)
>>> sorted(l,key=str)
6.2、用bisect来管理已排序的序列
bisect包含两个主要函数,bisect 和 insort,都利用二分查找算法在有序序列中查找或插入元素。
bisect 的表现可以从两个方面进行:
- bisect 有两个可选参数:lo 和 hi 来缩小搜寻范围,lo默认值是0,hi默认值是序列的长度len()。
- bisect函数其实是bisect_right函数的别名,还有一个bisect_left函数,区别在于新元素会放置于它相等的元素的前面
def grade(score,breakpoint=[60,70,80,90],grade='FDCBA'):
i = bisect.bisect(breakpoint,score)
return grade[i]
7、数组、内存、队列
7.1、当列表不是首选时
如果我们需要一个只包含数字的列表,那么array.array 比 list 更加高效。
创建数组需要一个类型码,类型码用来表示在底层的C语言应该存放怎样的数据类型。
类型代码 | C类型 | Python类型 | 最小大小(以字节为单位) |
---|---|---|---|
'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' |
签名int | INT | 2 |
'I' |
无符号整数 | INT | 2 |
'l' |
signed long | INT | 4 |
'L' |
无符号长整数 | INT | 4 |
'q' |
signed long long | INT | 8 |
'q' |
无符号long long | INT | 8 |
'f' |
float | float | 4 |
'd' |
double | float | 8 |
数组还提供从文件读取和存入文件的更快的方法。
from array import array
from random import random
floats = array('d',(random() for i in range(10**7)))
print(floats[-1]) fp = open('floats.bin','wb')
floats.tofile(fp)
fp.close() floats2 = array('d')
fp = open('floats.bin','rb')
floats2.fromfile(fp,10**7)
fp.close()
▲ 数组的排序:a = array.array(a.typecode, sorted(a))
7.2、内存=视图
memoryview 是一个内置类,能在不复制内容的情况下操作同一个数组的不同切片。
a = bytearray('aaaaaaa',encoding='utf8') b = a[:2]
b[:2] = b'bb'
print(a,b) # bytearray(b'aaaaaaa') bytearray(b'bb') ma = memoryview(a)
mb = ma[:2]
mb[:2] = b'bb' print(ma.tobytes(),mb.tobytes()) # b'bbaaaaa' b'bb'
使用场景是网络程序中socket接收和接收数据的解析
7.3、双向队列和其他形式的队列
collections.deque 类是一个线程安全,可以快速从两端添加或者删除元素的数据类型。
>>> from collections import deque
>>> dq = deque(range(10),maxlen=10)
>>> dq
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> dq.rotate(3) # 当n>0时,最右边n个元素移到最左边,当n<0时,最左边移到最右边
>>> dq
deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10)
>>> dq.rotate(-4)
>>> dq
deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], maxlen=10)
>>> dq.appendleft(-1) # 对已满的队列添加元素时,尾部元素会被删除
>>> dq
deque([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> dq.extend([11,22,33])
>>> dq
deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33], maxlen=10)
>>> dq.extendleft([10,20,30,40])
>>> dq
deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8], maxlen=10)
其他形式的队列:
queue:不同的线程可以利用这些数据类型交换信息。
multiprocessing:实现了自己的Queue,设计给进程间通信用的。
asyncio:为异步编程里的任务提供。
heapq:把可变序列当做堆队列或者优先队列使用。
Python序列构成的数组的更多相关文章
- 《流畅的Python》第二部分 数据结构 【序列构成的数组】【字典和集合】【文本和字节序列】
第二部分 数据结构 第2章 序列构成的数组 内置序列类型 序列类型 序列 特点 容器序列 list.tuple.collections.deque - 能存放不同类型的数据:- 存放的是任意类型的对象 ...
- 第2章 Python序列
Python序列类似于C或Basic中的一维.多维数组等,但功能要强大很多,使用也更加灵活.方便,Head First Python一书就戏称列表是“打了激素”的数组. Python中常用的序列结构有 ...
- Python当中的array数组对象
计算机为数组分配一段连续的内存,从而支持对数组随机访问:由于项的地址在编号上是连续的,数组某一项的地址可以通过将两个值相加得出,即将数组的基本地址和项的偏移地址相加.数组的基本地址就是数组的第一项的机 ...
- python数据分析 Numpy基础 数组和矢量计算
NumPy(Numerical Python的简称)是Python数值计算最重要的基础包.大多数提供科学计算的包都是用NumPy的数组作为构建基础. NumPy的部分功能如下: ndarray,一个具 ...
- Redis入门 – Jedis存储Java对象 - (Java序列化为byte数组方式)
Redis入门 – Jedis存储Java对象 - (Java序列化为byte数组方式) 原文地址:http://alanland.iteye.com/admin/blogs/1600685(欢迎转载 ...
- [Python笔记][第二章Python序列-复杂的数据结构]
2016/1/27学习内容 第二章 Python序列-复杂的数据结构 堆 import heapq #添加元素进堆 heapq.heappush(heap,n) #小根堆堆顶 heapq.heappo ...
- [Python笔记][第二章Python序列-tuple,dict,set]
2016/1/27学习内容 第二章 Python序列-tuple tuple创建的tips a_tuple=('a',),要这样创建,而不是a_tuple=('a'),后者是一个创建了一个字符 tup ...
- [python笔记][第二章Python序列-list]
2016/1/27学习内容 第二章 Python序列-list list常用操作 list.append(x) list.extend(L) list.insert(index,x) list.rem ...
- python学习笔记:python序列
python序列包括字符串.列表和元组三部分,下面先总的说一下python序列共有的一些操作符和内建函数. 一.python序列 序列类型操作符 标准类型的操作符一般都能适用于所有的序列类型,这里说一 ...
随机推荐
- C++ 简单实现 依赖注入(IOC)
由于C++ 不支持“反射机制”, 在C++中需要实现依赖注入或控制反转需要增加辅助程序.例如在Windows 开发程序中根据类名动态创建对象,需要在类定义中增加宏.本文主要介绍C++ Ioc的一种实现 ...
- ObjectMapper 对象和json相互转换
一.ObjectMapper ObjectMapper类是Jackson库的主要类.它提供一些功能将转换成Java对象匹配JSON结构,反之亦然.它使用JsonParser和JsonGenerator ...
- ubuntu 拨号上网
如果没有安装的用户,可以使用 sudo apt-get install pppoe pppoeconf 然后配置上网 sudo pppoeconf 最后,使用 sudo pon dsl-provide ...
- UI自动化的第一步(Python,pip,selenium,PyCharm安装配置)
一,py安装 1.python下载,安装,环境配置 地址:https://www.runoob.com/python/python-install.html 注意:安装时,要勾选自动配置环境变量.这样 ...
- Spring在Thread中注入Bean无效的解决方式
在Spring项目中,有时需要新开线程完成一些复杂任务,而线程中可能需要注入一些服务.而通过Spring注入来管理和使用服务是较为合理的方式.但是若直接在Thread子类中通过注解方式注入Bean是无 ...
- python selenium5 模拟点击+拖动+按照指定相对坐标拖动 58同城验证码
#!/usr/bin/python # -*- coding: UTF-8 -*- # @Time : 2019年12月9日11:41:08 # @Author : shenghao/10347899 ...
- SIP中的SDP offer/answer交换初探
1.引言 SDP的offer/answer模型本身独立与于利用它的高层协议.SIP是使用offer/answer模型的应用之一.RFC 3264 定义了offer/answer模型,但没有规定使用哪个 ...
- SSM框架警告/错误集合
警告: 1.使用Eclipse的Spring Elements组件的时候发现会提示有警告:Expect at least one bean match() 解决办法:项目可以正常运行,未有报错,在其他 ...
- linux 操作系统安装
操作系统安装 安装虚拟机软件:一路Next即可 VMWare:如果14版本不支持你的CPU,就换成12版本 Virtual Box:比VMWare小很多 安装ubuntu操作系统:比较美观,实用性强 ...
- 如何创建一个前端 React 组件并发布到 NPM
首先npm文档摆在这里: https://www.npmjs.cn/ 参考组件 https://github.com/rakuten-rex/rex-dropdownhttps://www.npmjs ...