我们把文本、列表和表格叫做数据火车。。。FOR命令通常能作用于数据火车上。      ---ABC Programmer's Handbook

不管是哪种数据结构,字符串、列表、字节序列、数组、XML元素,或是数据库查询结果,他们都共用一套丰富的操作:迭代、切片、排序、还有拼接。

1、内置序列类型概览

容器序列:list、tuple和collections.duque这些序列能存放不同类型的数据。

扁平序列:str、bytes、bytearray、memoryview和array.array这些序列只能容纳一种类型。

可变序列:list、bytearray、array.array、collections.duque和memoryview

不可变序列:tuple、str、bytes

可变序列从不可变序列那里继承了一些方法。

2、列表推导和可读性

列表推导只有一作用:生成列表。列表推导读起来更方便:

>>> symbols = "python"
>>> codes = [ord(symbol) for symbol in symbols] # 使用列表推导读起来更方便
>>> codes
[112, 121, 116, 104, 111, 110]

其他的写法如下(不太建议):

>>> codes = []
>>> for symbol in symbols:
... codes.append(ord(symbol))
...
>>> codes
[112, 121, 116, 104, 111, 110]

只用列表推导来创建新的列表,并且尽量保持简单,如果列表推导的代码超过了两行,那么就要考虑是不是要用for循环了。

python会忽略代码里的[],{}和()的换行。

列表推导不会再有变量泄露的问题:

>>> x = "my precious"
>>> dummy = [ord(x) for x in 'ABC']
>>> dummy
[65, 66, 67]
>>> x # 在python2中x的取值会是'C'
'my precious'

列表推导可以帮助我们过滤或者加工序列中的元素,其运行速度不一定会比map/filter组合慢。

>>> symbols = "python"
>>> beyond_ascii = [ord(s) for s in symbols if ord(s) > 110] # 这种方法不一定慢
>>> beyond_ascii
[112, 121, 116, 111]
>>>
>>> beyond_ascii = list(filter(lambda c:c > 110, map(ord, symbols)))
>>> beyond_ascii
[112, 121, 116, 111]

生成笛卡尔积,循环的顺序调整,颜色和尺寸显示的顺序也会跟着调整。

>>> colors = ['black', 'white']
>>> sizes = ['S', 'M', 'L']
>>> tshirts = [(color, size) for color in colors for size in sizes]
>>> tshirts
[('black', 'S'), ('black', 'M'), ('black', 'L'), ('white', 'S'), ('white', 'M'), ('white', 'L')]
>>> tshirts = [(color, size) for size in sizes
... for color in colors]
>>> tshirts
[('black', 'S'), ('white', 'S'), ('black', 'M'), ('white', 'M'), ('black', 'L'), ('white', 'L')]

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)
...
black S
black M
black L
white S
white M
white L

4、元组

元组其实是对数据的记录,其每个元素都存放了记录中一个字段的数据和响应的位置。

>>> lax_coordinates = (33.9425, -118.408056)   # 洛杉矶国际机场的经纬度
>>> city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014) # 东京市的一些信息
>>> traveler_ids = [('USA', ''), ('BRA', 'CE342567'), # 一个元组列表(country_code,passport_number)
... ('ESP', 'XDA205856')]
>>> for passport in sorted(traveler_ids): # passport变量被绑定在每个元组上
... print('%s/%s' % passport) # %运算符能被匹配到对应的元组元素上
...
BRA/CE342567
ESP/XDA205856
USA/31195855
>>> for country, _ in traveler_ids: # for分别提取元组里的元素,也叫做拆包。因为元组中的第二个元素没有用,就赋值给'_'占位符
... print(country)
...
USA
BRA
ESP

4.1 元组拆包

下面都是属于元组拆包的应用:

1、所有赋值只用一行声明就写完了:city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)

2、用%把passport元组里的元素对应到print函数的格式化字符串的空档中:('%s/%s' % passport)

元组拆包的要求是被可迭代对象中的元素数量必须要跟接受这些元素的元素的空档数一致。另外可以用'*'来处理多余的元素。

>>> latitude, longitude = (33.9425, -118.408056)  # 元组拆包,平行赋值
>>> latitude
33.9425
>>> longitude
-118.408056
>>> a = 1
>>> b = 2
>>> b, a = a, b # 交换两个变量的值
>>> a
2
>>> b
1
>>> divmod(20, 8)
(2, 4)
>>> t = (20, 8)
>>> divmod(*t) # 用*运算符把一个可迭代对象拆开作为函数的参数
(2, 4)

如同之前的例子所示,'_'是一个很好的占位符,另外还可以用'*'来处理剩下的元素。在python中,函数用*args来获取不确定数量的参数,这种概念被扩展到了平行赋值中。在平行赋值中,*前缀只能用在一个变量名前面,这个变量可以出现在赋值表达式的任何位置。

>>> a, b, *rest = range(5)
>>> a, b, rest
(0, 1, [2, 3, 4])
>>> a, b, *rest = range(3)
>>> a, b, rest
(0, 1, [2])
>>> a, b, *rest = range(2)
>>> a, b, rest
(0, 1, [])
>>> a, *body, c, d = range(5)
>>> a, body, c, d
(0, [1, 2], 3, 4)
>>> *head, b, c, d = range(5)
>>> head, b, c, d
([0, 1], 2, 3, 4)

接受表达式的元组是可以嵌套的,例如(a, b, (c, d))。

4.2 具名元组

collections.namedtuple是一个工厂函数,可以用来构建一个带字段名的元组和一个有名字的类--这个对调试程序有很大帮助。

>>> from collections import namedtuple
>>> #具名元组需要两个参数,一个是类名,一个是类的各字段的名字,由空格分隔开
>>> City = namedtuple('City', 'name country population coordinates')
>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) # 存放的数据要以一串参数的形式传入到构造函数中
>>> tokyo
City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
>>> tokyo.population # 通过字段名或者位置来获取字段的信息
36.933
>>> tokyo.coordinates
(35.689722, 139.691667)
>>> tokyo[1]
'JP'

5、切片

在列表list、元组tuple、字符串str这类序列都支持切片操作。

那为什么切片和区间会忽略最后一个元素?

  • 当只有最后一个位置信息时,可以快速看出有几个元素:range(3)和my_list[:3]都返回3个元素
  • 当起止位置都可见时,可以快速计算出长度,用stop-start即可
  • 便于利用任意一个下表把序列分割成不重叠的两部分,只要写my_list[: x]和my_list[x: ]即可。

可以用s[a: b: c]的形式对s在a和b之间以c为间隔取值。c的值为负数意味着反向取值。

>>> s = 'bicycle'
>>> s[::3]
'bye'
>>> s[::-1]
'elcycib'
>>> s[::-2]
'eccb'

6、对序列使用+和*

+:+号两侧的序列由相同类型的数据所构成,在拼接的过程,两个被操作的序列都不会被修改。

*:把一个序列复制几份然后再拼接起来,把这个序列乘以一个整数。

+和*不会修改原来的操作对象,而是构建一个全新的序列。

>>> l = [1, 2, 3]
>>> l * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> m = ['a', 'b']
>>> l + m
[1, 2, 3, 'a', 'b']

流畅的python--2 序列构成的数组的更多相关文章

  1. 流畅的python之序列

    python对开发者友好的根源在于:1.序列的泛型操作2.内置的元组和映身类型3.用缩进来架构的源码4.无需变量声明的强类型 序列数据共用的一套丰富的操作:迭代.切片.排序和拼接.内置序列类型:1.容 ...

  2. 《流畅的Python》第二部分 数据结构 【序列构成的数组】【字典和集合】【文本和字节序列】

    第二部分 数据结构 第2章 序列构成的数组 内置序列类型 序列类型 序列 特点 容器序列 list.tuple.collections.deque - 能存放不同类型的数据:- 存放的是任意类型的对象 ...

  3. 《流畅的python》读书笔记

    流畅的python 第1章 python数据模型 ---1.1 一摞Python风格的纸牌 特殊方法,即__method__,又被称为魔术方法(magic method)或者双下方法(dunder-m ...

  4. 流畅的python(笔记)

    流畅的python中有很多奇技淫巧,整本书都在强调如何最大限度地利用Python 标准库.介绍了很多python的不常用的数据类型.操作.库等,对于入门python后想要提升对python的认识应该有 ...

  5. python经典书籍必看:流畅的Python

    作者:熊猫烧香 链接:www.pythonheidong.com/blog/article/26/ 来源:python黑洞网 目标读者 本书的目标读者是那些正在使用 Python,又想熟悉 Pytho ...

  6. 流畅的python笔记

    鸭子类型协议不完全总结序列:len,getitem切片:getitemv[0]分量的取值和写值:getitem和setitemv.x属性的取值和写值:getattr和setattr迭代:1)iter, ...

  7. 点读系列《流畅的python》

    第1章 python数据模型 python的写法是由背后的魔法方法实现的,比如obj[key],解释器实际调用的是obj.__getitem__(key) 作者把魔法方法叫做双下方法,因为有两个下划线 ...

  8. 《流畅的Python》 第一部分 序章 【数据模型】

    流畅的Python 致Marta,用我全心全意的爱 第一部分 序幕 第一章 Python数据模型 特殊方法 定义: Python解释器碰到特殊句法时,使用特殊方法激活对象的基本操作,例如python语 ...

  9. Redis入门 – Jedis存储Java对象 - (Java序列化为byte数组方式)

    Redis入门 – Jedis存储Java对象 - (Java序列化为byte数组方式) 原文地址:http://alanland.iteye.com/admin/blogs/1600685(欢迎转载 ...

  10. 在python 中有时候我们用数组

    在python 中有时候我们用数组操作数据可以极大的提升数据的处理效率, 类似于R的向量化操作,是的数据的操作趋于简单化,在python 中是使用numpy模块可以进行数组和矢量计算. 下面来看下简单 ...

随机推荐

  1. bzoj2762-[JLOI2011]不等式组

    求 \(x=k\) 时满足一元一次不等式 \(ax+b<c\) 的个数. 解出 \(\frac{c-b}{a}\) 之后取整,得到合法区间,用树状数组维护. 注意 \(a\) 的值域是 \([- ...

  2. 通过流量清理防御DDoS

    导读 在2018年2月,世界上最大的分布式拒绝服务(DDoS)攻击在发起20分钟内得到控制,这主要得益于事先部署的DDoS防护服务. 这次攻击是针对GitHub–数百万开发人员使用的主流在线代码管理服 ...

  3. Spring 使用介绍(十一)—— Spring事件

    一.简介 spring事件是观察者设计模式的实现,主要有三个元素: 事件 spring事件由ApplicationEvent定义 监听者 由ApplicationListener定义 发布者 由App ...

  4. BZOJ4712洪水——动态DP+树链剖分+线段树

    题目描述 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到 山顶放了格水.于是小A面前出现了一个瀑布.作为平民的小A只好老实巴交地爬山堵水.那么 ...

  5. 安卓Android基础第三天——数据库,ListView

    数据库介绍sqlite问:什么情况下使用数据库?答:有大量相似结构的数据需要存储的时候 数据库的创建定义一个类继承SqliteOpenHelpercontext:上下文name:数据库名字,如&quo ...

  6. [BJWC2010] 严格次小生成树

    [BJWC2010]严格次小生成树算法及模板 所谓次小生成树,即边权之和第二小的生成树,但所谓严格,就是不能和最小的那个相等. 求解严格次小生成树的方法一般有倍增和LCT两种.当然LCT那么高级的我当 ...

  7. NOIP2018联赛总结

    NOIP2018联赛总结 Day 0 打了几个模板,看了一下别人的博客,背了一下vimrc Day 1 到了考场,先把vimrc配好 打开题目一先把三道题瞄了一眼,\(T1\)似乎是NOIP原题,\( ...

  8. 【CF802C】Heidi and Library(网络流)

    [CF802C]Heidi and Library(网络流) 题面 CF 洛谷 题解 前面两个Easy和Medium都是什么鬼玩意啊.... 不难发现如果这天的要求就是第\(a_i\)种书的话,那么\ ...

  9. 【BZOJ5304】[HAOI2018]字串覆盖(后缀数组,主席树,倍增)

    [BZOJ5304][HAOI2018]字串覆盖(后缀数组,主席树,倍增) 题面 BZOJ 洛谷 题解 贪心的想法是从左往右,能选就选.这个显然是正确的. 题目的数据范围很好的说明了要对于询问分开进行 ...

  10. tvs二极管应用电路

    瞬态电压抑制器(TVS)具有响应时间快.瞬态功率大.漏电流低.击穿电压偏差小.箝位电压较易控制.无损坏极限.体积小等优点.目前已广泛应用于计算机系统.通讯设备.交/直流电源.汽车.家用电器.仪器仪表等 ...