概述
目录:
本篇开始总结 Python 基本的数据结构,大部分情况下,这些数据结构就已经够用了,不需要重复造轮子。首先是序列及其相关的操作。
序列(Sequence)
标准库中提供了很多序列类型,都是C实现的,效率很高。容器序列(Container sequences):
list, tuple, collections.deque ...
容器序列持有的是所包含对象的引用,可以是任意类型。平坦序列(Flat sequences):
str, bytes, bytearray, memoryview, array.array
平坦序列物理上存储每个条目对应的内存空间的值,而不是作为不同的对象。
因此,平坦序列更加紧凑,但是他们只能保存原始的数值如字符,字节和数字。
根据可不可变分类:
可变的序列:
list, bytearray, array.array, collections.deque, memoryview
不可变序列:
tuple, str, bytes
如何快速生成一个序列?列表推导(List Comprehensions)
生成器表达式(Generator Expressions)
强烈推荐列表推导,用它实现的代码简洁,易读,执行效率高,堪称完美。
首先举一个例子:
取出一个字符串列表中所有小写的字符串,并组成列表
>>> words = ['The', 'quick', 'BROWN', 'Fox', 'jumped', 'OVER', 'the', 'Lazy', 'DOG']
>>> [word for word in words if word.islower()]
['quick', 'jumped', 'the']
列表推导格式以 [] 为标志,内容分为三部分 [A B C],A,B,C分别代表一个表达式,其中C可以省略。
对于上面的例子:A:word
B:for word in words
C:if word.islower()
首先看B,B的格式一般为 for x in xxx,表示从一个序列中逐个选取元素,也就是常用的 for in 结构。可以有多个for in,比如 for x in xxx for y in yyy。使用多个for的时候,就会生成所有组合。例如列举出不同颜色尺寸的T恤组合 :
>>> 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')]
然后看C,C提供一个判断条件,格式一般为 if xxx,其中可以用到B所给出的x,用于选取符合条件的条目。可以省略,也就意味着使用B生成的所有条目。
最后看A,A格式随意,可以使用B中给出的x(或者y),当然也可以不使用。
>>> [word[0] for word in words if word.islower()]
['q', 'j', 't']
>>> [3 for word in words if word.islower()]
[3, 3, 3]
列表推导时一般控制在一行以内,如果只有多行才能实现,那说明逻辑太复杂了,考虑别用列表推导了,展开吧。
生成器表达式和列表推导唯一的不同是用 () 包围而不是 [],如果不需要一次性生成整个列表,那么用生成器表达式更好。如下:
>>> (word for word in words if word.islower())
at 0x02F00288>
这样只是构造了一个生成器对象,每个元素会在需要用到的时候才进行构造,可以原封不动地用于 for in 结构,需要变成列表的时候也可以随时调用 list() 函数转化为列表。
元组(Tuple)
元组的主要用途:作为不可变的列表
作为没有字段名称的记录
元组解包:
>>> lax_coordinates = (33.9425, -118.408056)
>>> latitude, longitude = lax_coordinates # tuple unpacking
>>> latitude
33.9425
>>> longitude
-118.408056
作为函数参数就地展开,在前面加*就可以了:
>>> divmod(20, 8)
(2, 4)
>>> t = (20, 8)
>>> divmod(*t)
(2, 4)
具名元组(Named Tuples):
因为元组作为记录比较好用,因此出现了 namedtuple,在 collections 模块中。
使用 namedtuple 创建的实例消耗的内存和普通元组相同,因为字段的名字是存储在类中的。他们使用的内存比普通的类要少,因为它们不用在每个实例的 __dict__ 中存储属性。
使用示例:
>>> from collections import namedtuple
>>> Point = namedtuple('Point', 'x y')
>>> p = Point(3, 4)
>>> p
Point(x=3, y=4)
>>> p.x
3
>>> p[1]
4
namedtuple 有几个有用的属性和方法:_fields 类属性,保存所有字段名称
>>> Point._fields
('x', 'y')_make(iterable) 类方法,使用已经存在的序列或者 iterable 来创建 namedtuple
>>> point_tuple = (3, 4)
>>> p = Point._make(point_tuple)
>>> p
Point(x=3, y=4)_asdict() 实例方法,返回一个 OrderedDict,映射名称和对应的值。
>>> p._asdict()
OrderedDict([('x', 3), ('y', 4)])
总结:
Python 中序列的用法是大同小异的,基本上掌握了一个,其他的都差不多,剩下的就是可不可变,存储的是值还是引用需要注意下。
使用列表推导来构建序列能够让代码变得非常简洁,容易理解,推荐多尝试使用。
元组用来作为数据记录比较好用,namedtuple 使得元组在保持低内存消耗的情况下更加容易调试。
最后
以上就是留胡子金毛为你收集整理的fluent python 第二版_Fluent Python 笔记(二):序列基础的全部内容,希望文章能够帮你解决fluent python 第二版_Fluent Python 笔记(二):序列基础所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复