4

《流畅的Python》读书笔记----第二章 序列构成的数组

 1 year ago
source link: https://tfeima.github.io/2018/11/16/%E7%AC%AC%E4%BA%8C%E7%AB%A0%20%E5%BA%8F%E5%88%97%E6%9E%84%E6%88%90%E7%9A%84%E6%95%B0%E7%BB%84/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

《流畅的Python》读书笔记----第二章 序列构成的数组

发表于 2018-11-16

| 分类于 读书笔记

字数统计: 1.2k

本文为《流畅的Python》第二章,序列构成的数组的读书笔记

[toc]

第二章 序列构成的数组

Python内置序列类型

两种分类:

  • 容器序列:这些序列能存放不同类型的数据,并且存放的是它们所包含的对象的引用,比如list,tuple,collection.deque
  • 扁平序列:这类序列只能容纳一种数据类型,是一段连续的内存空间,比如str,bytes,bytearray,memoryview,array.array

按照元素能否被修改分类:

  • 可变序列:list,collection.deque,bytearray,memoryview,array.array
  • 不可变序列:str,tuple,bytes

列表推导式和生成器表达式

列表推导式的例子

symbols = 'abd79u'
codes = [ord(symbol) for symbol in symbols]

# 等价的for循环
codes = []
for symbol in symbols:
codes.append(ord(symbol))

使用列表推导式的一般原则:

  1. 只用列表推导式创建列表,并尽量保持简洁
  2. 如果列表推导式超过两行,最好使用for loop

列表推导式与filter和map的比较

例子:

symbols = 'abd79u'
beyond_ascii = [ord(s) for s in symbols if ord(s)>127]
# 用filter和map实现
beyond_ascii = list(filter(lambda x: x>127,map(ord,symbols)))

函数map有两个参数,第一个参数为函数名,第二个列表,函数将会作用于列表的每个元素,然后返回作用后的列表。filter也是两个参数,第一个为用于筛选的函数。

生成表达式

把列表推导式的[]改成(),表达式就变为了生成表达式,列表推导式与生成表达式的区别在于,若想要迭代一个按规则生成的序列,列表推导式会一次性地生成整个列表,然后将其保存在内存中,而生成表达式只有要迭代到某个元素的时候,才会去生成这个元素,并没有事先建立一个完整的列表,这样做可以大大的节省内存。

元组不仅仅是不可变的列表

元组拆包可以应用到任何可迭代对象上,但是可迭代对象元素数量必须跟接受这些元素的元组的空档数一样,可以用*忽略多余的元素。
例子

name,age = (tengfei,25)
# *运算符可以把一个可迭代对象拆开作为函数的参数
t = (25,3)
divmod(*t)
# 输出:(8,1),商和余数

# 平行赋值
a,b,*rest = range(5)
# a:0,b:1,rest:[2,3,4]

具名元组namedtuple

它可以用来构建一个带字段名的元组和一个有名字的类。

>>> from collections import namedtuple
# 需要两个参数:类名,类的各个字段的名字。后者可由数个字符串组成可迭代的对象或者用空格分开
>>> City = namedtuple('City','name country population coordinates')
>>> beijing = City('Beijing','China',1000,(35,110))
# 可以使用.或者索引来获取字段的信息
>>> beijign.country
'China'
>>> beijing[1]
'China'

s[a:b:c],在a,b之间以间隔c取值。当使用s[a:b:c]取值的时候,Python会自动调用s.__getitem__(slice[a:b:c])

如果赋值的对象是一个切片,那么赋值语句的左边必须是一个可迭代的对象,即使只有一个值。

使用+和*

需要注意的是,a*n语句中,如果a里的元素是其他可变对象的引用,比如a里的元素是list,比如a=[[1]],那么a = a*3语句得到的是包含3个引用的列表[[1],[1],[1]],如果要修改a中的某个元素,比如a[1][0]=2,那么会得到a变为[[2],[2],[2]]

序列的增量赋值+=和*=

当使用+=或*=时,Python会自动调用__iadd____imul__

list.sort方法和内置函数sorted

list.sort会对列表就地排序,它的返回值是None,所以不能使用max(list.sort)等串联的用法。sorted(list)会对list进行排序,并返回排序后的结果,但不是原地的,也就是list并不会发生改变。

它俩都有一个key参数,这个参数接受一个只有一个参数的函数(比如len,srt.lower),这个函数作用于list的每一个元素,并返回一个结果,sorted就按照这个返回的结果给list排序。

当列表不是首选时

实际应用中,除了list,在一些特殊的场景中,可以使用其他的序列结构,以提高效率。比如

  • 存储浮点数可以使用array
  • 如果需要频繁的先进先出操作,可以选择使用deque
  • 如果频繁需要检查一个元素是否在集合中,可以选择set

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK