《Fluent Python》读书笔记——第二章序列构成的数组

摘要

Python的序列类型很丰富,有list,tuple,str,bytes,bytearray,memoryview rray.array等。
可以分为容器序列扁平序列
容器序列存放的任意类型的对象的引用,
扁平序列存放的是值而不是引用

序列类型按能否被修改还可分为可变序列不可变序列

这一章主要讲了list,tuple这两种序列类型

列表推导

使用列表推导的通常原则是:
只用列表推导来创建新的列表,并且尽量保持简短。如果列表推导的代码超过了两行,你可能就要考虑是不是得用 for 循环重写了。

列表推导的基本语法:

a = [obj for obj in objs]

列表推导的优点:

  • 可读性好
  • Python3中不存在变量泄露的问题

生成器表达式

生成器表达式的语法跟列表推导差不多,只不过把方括号换成圆括号而已

优点:
生成器表达式背后遵守了迭代器协议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这个列表传递到某个构造函数里

元组

拆包

  • 平行赋值:把一个可迭代对象里的元素,一并赋值到由对应的变量组成的元组中。
>>> lax_coordinates = (33.9425, -118.408056)
>>> latitude, longitude = lax_coordinates # 元组拆包
>>> latitude
33.9425
>>> longitude
-118.408056
  • 不使用中间变量交换两个变量的值
>>> b, a = a, b
  • 用 * 运算符把一个可迭代对象拆开作为函数的参数
>>> divmod(20, 8)
(2, 4)
>>> t = (20, 8)
>>> divmod(*t)  # *t作为函数的参数
(2, 4)
>>> quotient, remainder = divmod(*t)
>>> quotient, remainder
(2, 4)

  • 用*来处理剩下的元素
>>> 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, [])

具名元组

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
>>> City._fields  # 类属性
('name', 'country', 'population', 'coordinates')
>>> LatLong = namedtuple('LatLong', 'lat long')
>>> delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))
>>> delhi = City._make(delhi_data) # 用 _make() 通 过 接 受 一 个 可 迭 代 对 象 来 生 成 这 个 类 的 一 个 实 例
>>> delhi._asdict() 
OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population',
21.935), ('coordinates', LatLong(lat=28.613889, long=77.208889))])
>>> for key, value in delhi._asdict().items():
print(key + ':', value)
name: Delhi NCR
country: IN
population: 21.935
coordinates: LatLong(lat=28.613889, long=77.208889)
>>>

切片

给切片赋值

>>> l = list(range(10))
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[2:5] = [20, 30]
>>> l
[0, 1, 20, 30, 5, 6, 7, 8, 9]
>>> del l[5:7]
>>> l
[0, 1, 20, 30, 5, 8, 9]
>>> l[3::2] = [11, 22]
>>> l
[0, 1, 20, 11, 5, 22, 9]
>>> l[2:5] = 100 ➊
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>> l[2:5] = [100]
>>> l
[0, 1, 100, 22, 9]

对序列使用+*

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

序列的增量赋值

+=背后的特殊方法是__iadd__(就地加法)

• 不要把可变对象放在元组里面。
• 增量赋值不是一个原子操作。
• 查看 Python 的字节码并不难,而且它对我们了解代码背后的运行机制很有帮助。

排序

如果一个函数或者方法对对象进行的是就地改动,那它就应该返回None,好让调用者知道传入的参数发生了变动,而且并未产生新的对象

list.sort方法就地排序,改变了原列表
sorted()函数则会新建一个列表作为返回值

list.sortsorted()的两个关键字参数
reverse

如果被设定为 True,被排序的序列里的元素会以降序输出(也就是说把最大值当作最小值来排序)。这个参数的默认值是 False。

key

一个只有一个参数的函数,这个函数会被用在序列里的每一个元素上,所产生的结果将是排序算法依赖的对比关键字。比如说,在对一些字符串排序时,可以用 key=str.lower 来实现忽略大小写的排序,或者是用 key=len 进行基于字符串长度的排序。这个参数的默认值是恒等函数(identity function),也就是默认用元素自己的值来排序。

当列表不是首选时

数组

当需要一个只包含数字的列表是,array.arraylist更高效

内存视图memoryview

memoryview 能让用户在不复制内容的情况下操作同一个数组的不同切片。

collections.deque

collections.deque 类(双向队列)是一个线程安全、可以快速从两端添加或者删除元素的数据类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值