流畅的python python 序列
内置序列
- 容器类型
- list 、tuple和collections.deque这些序列能放入不同的类型的数据
- 扁平序列
- str、byets、bytearray、memoryview(内存视图)和array.array(数组)
- 可变序列
- list、bytearray、array.array、collections.deque和memoryview
- 不可变序列
- tuple、str和bytes
可变序列所拥有的方法是在不可变序列的基础上增加的.
列表推导式
简单使用
列表是我们常见的可变序列,他是容器类型的这里主要介绍列表推导式
列表推导式是构建列表的快捷方式
例子:
将一个字符串转换成Unicode码位的列表
symbols='abcde'
code=[]
for item in symbols:
code.append(ord(item)) print(code)
#[97, 98, 99, 100, 101]
再来看列表推导式:
symbols='abcde'
code=[ord(item) for item in symbols]
print(code)
- 列表推导式能让你的程序变的更加简洁
- 列表推导式只用来创建新的列表,并且尽量保持简短
- 列表推导式可以帮助我们把一个序列或者其他可迭代的对象中的元素过滤或者是加工,然后再创建一个新的列表
列表推导式的过滤
借助刚刚的例子,我想得到一个Unicode码位大于99的,那么我们用内置函数map和filter来构造看看:
symbols='abcde' filter_symbols=list(filter(lambda x:x>99,map(ord,symbols))) print(filter_symbols)
#[100, 101]
那么列表推导式呢?
symbols='abcde' filter_symbols=[ord(item) for item in symbols if ord(item)>99]
print(filter_symbols)
#[100, 101]
从上面的例子可以看出来,列表推导式更加具有可读性
注意列表推导式变量泄露问题
在python2.x中for的关键字可能会影响到其他同名的变量
例子:
x='变量泄露'
result=[x for x in 'ABC']
print(x)
#'C'
x原本的值被取代了,这不是我们想要看到的,那么这就叫变量泄露
在python3中是不会出现的.
x='变量泄露' result=[x for x in 'ABC'] print(x)#变量泄露
列表推导式/生成器表达式/以及集合和字典的推导在python3中都有了自己的局部作用域.所以表达式的上下文中的变量还可以变正常的使用
元组
元组和记录
元组其实是对数据的记录,如果紧紧理解元组是不可变的列表,那么我们可能忽略了他的位置信息的重要性,
如果把元组当做一些字段的集合,那么数量和位置就显的异常重要
name,age=('ming',12)
year,month,day = (2018,8,16)
tup=('ming','大帅比')
print('%s:%s'%tup)
那么上面的例子就可以看出位置信息的重要性,那么列表也可以实现上面的拆包机制,但是为什么不用列表?
因为元组的是不可变序列的,如果你用列表来进行位置的拆包,如果你的列表insert了一个值,那么你的信息将会全部乱套.
元组的拆包
在上面将元组的元素分别赋值给变量,name,age同样用一个%运算符就把tup的元素对应到了格式字符串的空档中,这些都是对元组拆包的应用
元组的拆包可以应用到任何可迭代的对象上,但是被可迭代对象的元素数量必须跟接收这些元素的空档数一致,除非我们用*
不用中间变量交换两个变量的值
a,b=b,a
用*运算符把一个可迭代对象拆开作为函数的参数:
t=(20,8)
q,r=divmod(*t)
print(q,r)
#2,4
用*在处理剩下的元素
a,b,*rest=range(5)
print(a,b,rest)#0 1 [2, 3, 4] a,b,*rest=range(3)
print(a,b,rest)#0 1 [2] a,b,*rest=range(2)
print(a,b,rest)# 0 1 []
*可以出现在赋值表达式的任意位置
a,*rest,b=range(5)
print(a,rest,b)#0 [1, 2, 3] 4 *rest,a,b=range(5)
print(rest,a,b)#[0, 1, 2] 3 4
切片
在python中,像列表/元组/字符串这类数列支持切片操作
为什么切片和区间会忽略最后一个元素
- 当只有最后一个位置信息时,我们可以快速看出切片和区间的元素
- range(3), my_list=[:3]
- 当起始和终止位置可见时,可以快速计算出切片和区间的长度,用最后一个下标减去第一个下标
- 分割成不重复的两部分
- my_list[:x] my_list[x:] 那么这两个切片是不存在重复的元素
切片的赋值:
l=list(range(10))
l[2:5]=[20,30]
print(l)#[0, 1, 20, 30, 5, 6, 7, 8, 9] del l[5:7]
print(l)#[0, 1, 20, 30, 5, 8, 9] l[3::2]=[11,22]
print(l)#[0, 1, 20, 11, 5, 22, 9] # l[2:4]=100'#报错 切片的赋值必须是可迭代的对象
# print(l)
l[2:4] ='abcde' #赋值范围超过切片范围,同样的会把赋值的内容全部放入列表中
#[0, 1, 'a', 'b', 'c', 'd', 'e', 5, 22, 9] 且不会挤出列表原有的元素
对序列使用+和*/增量赋值
对序列使用+和*
+和*都遵循不修改原有的操作对象,而是构建一个新的序列
board=[['_']*3 for i in range(3)]
board[1][2]='x'
print(board)#[['_', '_', '_'], ['_', '_', 'x'], ['_', '_', '_']]
#列表推导式,每次执行的时候都会新创建一个['_'] weird_board=[['_']*3]*3
weird_board[1][2]='x'
print(weird_board)#[['_', '_', 'x'], ['_', '_', 'x'], ['_', '_', 'x']]
#如果直接在本身列表里*嵌套的列表,那么里面嵌套的列表都是指同一个对象
#那么可能结果不是你想要的
序列的增量赋值
对于可变的序列来说,+=,*=内部调用了可变序列对象的__iadd__方法或者__imul__方法
那么该可变序列就会就地改动,并不会指向新的对象,就是说他的id是不变的
l=[1,3,4]
print(id(l))
l*=4
print(id(l))
#
#
对于不可变序列来说+=和*=会退一步的调用__add__,和__mul__方法
那么该方法会进行重新的赋值拼接操作,然后追加到新的元素中
l=(1,3,4)
print(id(l))
l*=4
print(id(l))
#
#
- 对不可变序列进行重复拼接操作的话,效率会很低,因为每次都有一个新对象,而且解释器需要把原来的对象中的元素先赋值到新的对象里,然后再追加新的元素
+=的一个有趣例子:
t=(1,2,[30,40])
t[2]+=[50,60]
#运行后,代码报错 #但是再打印t发现元素已经修改了
#我们可以用捕捉异常来看
try:
t=(1,2,[30,40])
t[2]+=[50,60] except Exception as e:
print(t)#(1, 2, [30, 40, 50, 60])
我们可以看到t[2]=t[2]+[50,60],先进行列表的相加,我们知道这一步是可以实现的,但是当我们赋值到t[2]的时候,因为t是一个元组是不可以修改的序列当然就报错了
但是我们的t[2]+[50,60]这一部已经执行了,就是说t[2]列表对象的值已经被修改了
所以在报错的同时元组也被修改了
bisect模块
bisect模块包含两个主要函数,bisect和insort,两个函数都是利用二分查找算法来在有序的序列中查找或者插入元素
用bisect来搜索
bisect(haystack,needle)在haystack(干草垛)里搜索needle(针)的位置,haystack必须是一个有序的序列.
例子:
import bisect
import sys
HAYSTACK=[1,4,5,6,8,12,15,20,21,23,23,26,29,30]
NEEDLES=[0,1,2,5,8,10,22,23,29,30,31]
ROW_FMT='{0:2d}@{1:2d} {2}{0:<2d}' def demo(bisec_fn):
for needle in reversed(NEEDLES):
position = bisec_fn(HAYSTACK,needle)
offset = position* ' |'
print(ROW_FMT.format(needle,position,offset)) if __name__ == '__main__':
if sys.argv[-1] == 'left':
bisect_fn = bisect.bisect_left
else:
bisect_fn = bisect.bisect
print('HAYSTACK->',' '.join('%2d'%n for n in HAYSTACK))
demo(bisect_fn) HAYSTACK-> 1 4 5 6 8 12 15 20 21 23 23 26 29 30
31@14 | | | | | | | | | | | | | |31
30@14 | | | | | | | | | | | | | |30
29@13 | | | | | | | | | | | | |29
23@11 | | | | | | | | | | |23
22@ 9 | | | | | | | | |22
10@ 5 | | | | |10
8@ 5 | | | | |8
5@ 3 | | |5
2@ 1 |2
1@ 1 |1
0@ 0 0
用bisect.insort插入新元素
在得到一个有序的序列之后,我们插入新元素仍然想保持有序的序列
那么我们用insort(seq,item)把变量item插入到seq中,并保持seq升序顺序.
例子:
import random
import bisect
SIZE=7
my_list=[]
for i in range(SIZE*2):
new_item = random.randrange(SIZE * 3)
bisect.insort(my_list,new_item)
print('%2d ->'%new_item,my_list)
容器的选择
并不是选择序列容器的时候都要选择列表,虽然列表很强大,但是我们在选择的时候需要根据我们的需求来加以衡量.
比如我们存放一个1000万个浮点数的话,数组(array)的效率要高得多.因为数据背后存的并不是float对象,而是数字的机器翻译也就是字节表述.
当然如果要频繁的对序列做先进先出的操作,那么可以用deque双端队列.
流畅的python python 序列的更多相关文章
- Python sequence (序列)
序列简介 sequence 是一组有序元素的组合 序列可以是多个元素,也可以一个元素都没有 序列有2种:tuple(定值表).List(表) D:\python\Python_Day>pytho ...
- Python基本序列-字典
Python 基本序列-字典 字典(dict)是"键-值 对"的无序可变序列,字典中的每个元素包含两部分,"键"和"值". 字典中的&quo ...
- Python常见序列详解
一.Python中序列的分类 常见序列类型包括字符串(普通字符串和unicode字符串),列表和元组.所谓序列,即成员有序排列,可通过下标访问. 二.Python序列通用操作 下面我们将分别以字符串. ...
- 孤荷凌寒自学python第八天 初识Python的序列之元组
孤荷凌寒自学python第八天 Python的序列之元组 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) (同步音频笔记:https://www.ximalaya.com/keji/19103 ...
- python --- Python中的callable 函数
python --- Python中的callable 函数 转自: http://archive.cnblogs.com/a/1798319/ Python中的callable 函数 callabl ...
- Micro Python - Python for microcontrollers
Micro Python - Python for microcontrollers MicroPython
- 从Scratch到Python——python turtle 一种比pygame更加简洁的实现
从Scratch到Python--python turtle 一种比pygame更加简洁的实现 现在很多学校都开设了Scratch课程,学生可以利用Scratch创作丰富的作品,然而Scratch之后 ...
- 从Scratch到Python——Python生成二维码
# Python利用pyqrcode模块生成二维码 import pyqrcode import sys number = pyqrcode.create('从Scratch到Python--Pyth ...
- [Python]Python 使用 for 循环的小例子
[Python]Python 使用 for 循环的小例子: In [7]: for i in range(5): ...: print "xxxx" ...: print &quo ...
- [python]python 遍历一个list 的小例子:
[python]python 遍历一个list 的小例子: mlist=["aaa","bbb","ccc"]for ss in enume ...
随机推荐
- msbuild,Build failed with Error MSB3073 exited with code 1
1. 接手以前的老项目,因为项目比较大,所以用Developer Command Prompt 的msbuild命令编译比较快一些,常用命令如下 devenv /? 帮助 ms ...
- How to manually remove an infected file from your computer
http://blog.csdn.net/pipisorry/article/details/41258577 How to manually remove an infected file from ...
- sublime text 3 修改侧边栏字体
安装PackageResourceViewer快捷键 Ctrl+Shift+P 打开 Command Palette 输入 Package Control:Install 回车, 等待加载packag ...
- JVM内存监控:visualVM jconsole jstatd jmap
本文是亲自测试的详细配置过程,不是转载而且linux下不需修改/etc/hosts文件 由于在建项目的需要,监控tomcat的内存使用,检查内存泄漏的情况.其实JDK自身已经提供了很多工具,都在JAV ...
- FastDFS单机搭建以及java客户端Demo
http://blog.csdn.net/u012453843/article/details/69951920 http://blog.csdn.net/xyang81/article/detail ...
- Editing a Book UVA - 11212 IDA*
You have n equal-length paragraphs numbered 1 to n . Now you want to arrange them in the order of 1 ...
- ORA-06519: 检测到活动的自治事务处理,已经回退
写了一个函数,由于在定义时加入了 create or replace function F_计算结果(In_参数 varchar2) return number is --使用自治事务PRAGMA A ...
- 第一百九十五节,jQuery EasyUI,Resizable(调整大小)组件
jQuery EasyUI,Resizable(调整大小)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Resizeable(调整大小)组 ...
- Struts2 是什么?
Struts2是流行和成熟的基于MVC设计模式的Web应用程序框架. Struts2不只是Struts1下一个版本,它是一个完全重写的Struts架构. WebWork框架开始以Struts框架为基础 ...
- web开发之php--- mvc 模式
http://www.cnblogs.com/archy_yu/p/4229929.html