python读书笔记2000_流畅的python读书笔记-第二章Python 数据结构

列表表达式

>>> symbols = '$¢£¥€¤'

>>> codes = [ord(symbol) for symbol in symbols]

>>> codes

[36, 162, 163, 165, 8364, 164]

生成器表达式(节省内存)

>>> symbols = '$¢£¥€¤'

>>> tuple(ord(symbol) for symbol in symbols) ➊

(36, 162, 163, 165, 8364, 164)

>>> import array

>>> array.array('I', (ord(symbol) for symbol in symbols)) ➋

array('I', [36, 162, 163, 165, 8364, 164])

元素拆包

latitude, longitude = lax_coordinates # 元组拆包

不用中间变量交换值

b, a = a, b

_用来临时挡住不要的对象

_, filename = os.path.split('/home/luciano/.ssh/idrsa.pub')

平行赋值

>>> 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)

解包

可见在调用参数的时候使用*号可以自动解包

def add(x,y):

print x+y

para = (1,2)

add(*para)

同理如果是两个星号的话,就是带有**号的字典,自动解包

def add(x,y):

print x+y

kkwd = {'x' :1,'y':2}

add(**kkwd)

嵌套元素拆包

metro_areas = [

('Tokyo','JP',36.933,(35.689722,139.691667)), # ➊

('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),

('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),

('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),

('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),

]

for name, cc, pop, (latitude, longitude) in metro_areas: # ➋

if longitude <= 0: # ➌

print(fmt.format(name, latitude, longitude))

具名元组

Card = collections.namedtuple('Card', ['rank', 'suit'])

>>> 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) ➋

>>> 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)

>>>

❶ _fields 属性是一个包含这个类所有字段名称的元组。

❷ 用 _make() 通过接受一个可迭代对象来生成这个类的一个实例,它

的作用跟 City(*delhi_data) 是一样的。

❸ _asdict() 把具名元组以 collections.OrderedDict 的形式返

回,我们可以利用它来把元组里的信息友好地呈现出来。

列表或元组的方法和属性(那些由object类支持的方法没有

列出来) page 84

切片

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

当只有最后一个位置信息时,我们也可以快速看出切片和区间里有

几个元素:range(3) 和 my_list[:3] 都返回 3 个元素。

当起止位置信息都可见时,我们可以快速计算出切片和区间的长

度,用后一个数减去第一个下标(stop - start)即可。

这样做也让我们可以利用任意一个下标来把序列分割成不重叠的两

部分,只要写成 my_list[:x] 和 my_list[x:] 就可以了,如下所

示。

>>> l = [10, 20, 30, 40, 50, 60]

>>> l[:2] # 在下标2的地方分割

[10, 20]

>>> l[2:]

[30, 40, 50, 60]

>>> l[:3] # 在下标3的地方分割

[10, 20, 30]

>>> l[3:]

[40, 50, 60]

步进切片

对seq[start:stop:step] 进行求值的时候,Python 会调用

seq.__getitem__(slice(start, stop, step))。

+=

+= 背后的特殊方法是 iadd (用于“就地加法”)。但是如果一个类

没有实现这个方法的话,Python 会退一步调用 add 。考

+= 的概念也适用于 *=,不同的是,后者相对应的

是 imul

好工具

Python Tutor(http://www.pythontutor.com)是一个对 Python 运行原理进行

可视化分析的工具。

内置函数sorted

一个只有一个参数的函数,这个函数会被用在序列里的每一个元素

上,所产生的结果将是排序算法依赖的对比关键字。

reverse

如果被设定为 True,被排序的序列里的元素会以降序输出

注意并不是简单的把排序结果给反过来,是降序(按照之前的反排序)

数组

如果我们需要一个只包含数字的列表,那么 array.array 比 list 更高效。

数组支持所有跟可变序列有关的操作,包括 .pop、.insert 和.extend。

另外,数组还提供从文件读取和存入文件的更快的方法,如.frombytes 和 .tofile。

示例代码

>>> from array import array ➊

>>> from random import random

>>> floats = array('d', (random() for i in range(10**7))) ➋

>>> floats[-1] ➌

0.07802343889111107

>>> 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()

>>> floats2[-1] ➐

0.07802343889111107

>>> floats2 == floats ➑

True

结论:

array.tofile 和 array.fromfile 用 起来很简单。

用 array.fromfile 从一个二进制文件里读出 1000 万个 双精度浮点数只需要 0.1 秒,

这比从文本文件里读取的速度要快 60倍,因为后者会使用内置的 float 方法把每一行文字转换成浮点数。

列表和数组的属性和方法 page110

NumPy 和 SciPy

NumPy 和 SciPy 提供的高阶数组和矩阵操作,Python 成为科学计

算应用的主流语言。

双向队列和其他形式的队列

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) ➋

>>> 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)

❶ maxlen 是一个可选参数,代表这个队列可以容纳的元素的数量

❹ 在尾部添加 3 个元素的操作会挤掉 -1、1 和 2。

列表和双向队列 page 119

小总结

列表表达式 和 生成器表达式(元祖省内存)很好用

元祖的拆包十分神奇,尤其是*号的存在

具名元组的实例也很节省空间,有点像模拟字典使用,._asdict() 方法来把记录变成 OrderedDict 类型

切片是基本用法,给切片赋值是个好的修改方式

+=

增量赋值 += 和 *= 会区别对待可变和不可变序列。

在遇到不可变序列时,这两个操作会在背后生成新的序列。

但如果被赋值的对象是可变的,那么这个序列会就地修改

sorted 函数,只需要一个比较方法key

纯数字数组用 array.array比较好,NumPy 和 SciPy科学计算神奇世界

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值