惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Vulnerabilities – Threatpost
Google DeepMind News
Google DeepMind News
T
Threatpost
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
Security Latest
Security Latest
C
Cisco Blogs
Spread Privacy
Spread Privacy
Simon Willison's Weblog
Simon Willison's Weblog
L
LINUX DO - 热门话题
Know Your Adversary
Know Your Adversary
L
LINUX DO - 最新话题
P
Privacy & Cybersecurity Law Blog
SecWiki News
SecWiki News
O
OpenAI News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
H
Hacker News: Front Page
Scott Helme
Scott Helme
C
Check Point Blog
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
爱范儿
爱范儿
博客园 - 【当耐特】
H
Heimdal Security Blog
The Hacker News
The Hacker News
罗磊的独立博客
C
CERT Recently Published Vulnerability Notes
美团技术团队
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
SegmentFault 最新的问题
Last Week in AI
Last Week in AI
Project Zero
Project Zero
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享
The Register - Security
The Register - Security
A
Arctic Wolf
酷 壳 – CoolShell
酷 壳 – CoolShell
G
GRAHAM CLULEY
L
Lohrmann on Cybersecurity
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
Attack and Defense Labs
Attack and Defense Labs
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
Latest news
Latest news
I
InfoQ
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Y
Y Combinator Blog
J
Java Code Geeks
S
Security @ Cisco Blogs

晚花行乐

马克卡尼在2026年达沃斯论坛上的讲话(阅读材料) | 晚花行乐 鸡娃如何用力才是恰到好处 | 晚花行乐 读万卷书,行万里路的辩证关系 | 晚花行乐 反对培训机构掐尖招生 | 晚花行乐 小泽和建国会谈最后10分钟全文(阅读材料) | 晚花行乐 来看看 DeepSeek 怎么鸡娃 | 晚花行乐 谈谈基本功 | 晚花行乐 惠普 ProDesk SFF PC 各系列参数对比 | 晚花行乐 解决瘦客户机上安装 Debian 12 启动失败问题 | 晚花行乐 意拾喻言:老外写的文言文 | 晚花行乐 笠翁对韵中的典故(十三元) | 晚花行乐 谈谈中考取消四小门 | 晚花行乐 亚马逊云科技产品免费试用攻略(3) - 对象存储服务 | 晚花行乐 在 Windows 10 LTSC 版本上安装 WSL2 | 晚花行乐 Debian 12 的常用配置项 | 晚花行乐 在 Debian 12 上安装 Nvidia 显卡驱动程序 | 晚花行乐 解决 Debian 12 关机失败问题 | 晚花行乐 解决 VS Code 自动更新版本后卡在连接界面 | 晚花行乐 观看巴黎奥运会有感 | 晚花行乐 在 Windows10 上安装惠普旧打印机驱动程序 | 晚花行乐 欢迎关注公众号:晚花行乐 | 晚花行乐 如何编写拼写检查器 | 晚花行乐 亚马逊云科技产品免费试用攻略(2) - 云服务器 | 晚花行乐 Pandas 中 axis 参数的理解(附实例) | 晚花行乐 我打算命个名,叫什么什么 Manager | 晚花行乐 上海武康路历史建筑一览 | 晚花行乐 Python 实现简单的数学表达式解析并处理 | 晚花行乐 观看马拉松的感悟 | 晚花行乐 Python 保存 Cookies 到文件并再次读取 | 晚花行乐 如何为 Hugo 静态网站添加评论功能 | 晚花行乐 Linux 共享打印服务 CUPS | 晚花行乐 如何为 Hugo 静态网站添加搜索功能 | 晚花行乐 解决 CSV 文件的第一列不能解析 | 晚花行乐 亚马逊云科技产品免费试用攻略(1) - 注册账户 | 晚花行乐 第二幕 Atma 的闲聊 | 晚花行乐 第二幕野蛮人的语音 | 晚花行乐 古入声和普通话平声对照 | 晚花行乐 第一幕的背景音乐 | 晚花行乐 第二幕亚马逊的语音 | 晚花行乐 第一幕的亚马逊的语音 | 晚花行乐 第一幕的野蛮人的语音 | 晚花行乐 MacOS 的彩蛋:Here's to the crazy ones | 晚花行乐 笠翁对韵的基本知识 | 晚花行乐 笠翁对韵中的典故(十二文) | 晚花行乐 笠翁对韵中的典故(十一真) | 晚花行乐 笠翁对韵中的典故(十灰) | 晚花行乐 杭州景点的楹联 | 晚花行乐 adb keycode 大全 | 晚花行乐 Scikit-learn 学习笔记(0)名词术语 | 晚花行乐 Scikit-learn 学习笔记(3)监督学习的例子 | 晚花行乐 SQLite 文档的学习笔记(1)长期支持计划 | 晚花行乐 SQLite 文档的学习笔记(2)测试方法 | 晚花行乐 笠翁对韵中的典故(九佳) | 晚花行乐 Ansible 如何检查一个程序的版本 | 晚花行乐 Ansible 如何检查一个文件夹是否存在 | 晚花行乐 pip 配置文件详解 | 晚花行乐 Ansible 如何检查一个URL是否正常 | 晚花行乐 Ansible 如何修改 iptables 规则 | 晚花行乐 Ansible 指定 playbook 运行的主机 | 晚花行乐 Ansible 如何清空文件夹 | 晚花行乐 Ansible 如何在本机执行命令 | 晚花行乐 笠翁对韵中的典故(八齐) | 晚花行乐 Python 中 Defaultdict 的理解 | 晚花行乐 《伊索寓言》电子书 | 晚花行乐 菲伯尔钢琴伴奏:第二册 | 晚花行乐 Python 的 Keyword-Only Arguments 理解 | 晚花行乐 Python 的 函数参数处理机制 | 晚花行乐 瓦瑞夫在第一幕的闲聊 | 晚花行乐 瓦瑞夫在第一幕的任务提示 | 晚花行乐 第一幕的女巫语音 | 晚花行乐 《Fluent Python》 读书笔记:文本和字节序列 | 晚花行乐 第一幕的罗格语音 | 晚花行乐 第一幕的圣骑士语音 | 晚花行乐 第一幕的男巫语音 | 晚花行乐 第一幕的旁白 | 晚花行乐 第一幕的恶魔 | 晚花行乐 Python 中 Element Tree 的理解 | 晚花行乐 笠翁对韵中的典故(七虞) | 晚花行乐 笠翁对韵中的典故(五微) | 晚花行乐 笠翁对韵中的典故(六鱼) | 晚花行乐 笠翁对韵中的典故(一东) | 晚花行乐 笠翁对韵中的典故(二冬) | 晚花行乐 笠翁对韵中的典故(三江) | 晚花行乐 笠翁对韵中的典故(四支) | 晚花行乐 姜太公钓鱼 | 晚花行乐 武王建立周朝 | 晚花行乐 大禹治水 | 晚花行乐 尧舜让位 | 晚花行乐 黄帝战蚩尤 | 晚花行乐 上下五千年-精简版 | 晚花行乐 成功修复鼠标按键 | 晚花行乐 横向的Word文档怎么加页眉页脚 | 晚花行乐 商标通用化的故事:商标代替商品名 | 晚花行乐 搜索空文件夹的批处理程序 | 晚花行乐 Sn0wbreeze不能运行? | 晚花行乐 天线的驻波比 | 晚花行乐 天线参数:增益Gain | 晚花行乐 天线参数:方向图Radiation pattern | 晚花行乐 本拉登别墅的Google Earth坐标 | 晚花行乐 宜家帕克斯(PAX)衣柜的拼装过程 | 晚花行乐
《Fluent Python》 读书笔记:序列 | 晚花行乐
2021-12-05 · via 晚花行乐

本章主要讨论序列(sequence)

这篇文章 也介绍了序列类型的特点。

内置序列的类别

内置序列(built-in sequence)类型可以分为以下几种:

容器序列

看起来能存放任意类型对象,其实存放的只是对任意类型对象的引用。

比如:list,tuple,collections.deque

扁平序列

一段连续的内存空间,存放的是真实的值,而不是引用。只能存放字符、字节、数值等基础类型。

比如:str, bytes, bytesarray, memoryview, array.array

tuple 的存在意义

许多 Python 教程中把 tuple 称为“不可变的list”,然而这并没有完全概括 tuple 的特点。

tuple 除了看作不可变的列表,还可以用于没有字段名的记录:元组中每个元素的记录都存放了记录中一个字段的数据,所以元素的位置也赋予了信息。

如果仅仅把 tuple 理解为列表,那么元素的个数和他们的位置就没有意义,但是如果把 tuple 当作一些字段的集合,那么数量和位置信息就变得非常重要了。

tuple 拆包

拆包 unpacking 的写法简洁又美观,有下面一些使用场景。

常规拆包

常规的拆包方式,如下所示:

a, b = ('1', '2')

%号 拆包

除了常规拆包之外,还有其他的方式,比如:

>>> print('%s: %s' % ('1', '2'))
1: 2

下划线占位

下划线作为占位符。如果我们只对 tuple 中一些位置的元素感兴趣,而对其他位置的没有用,那么可以用下划线做占位符。比如:

>>> a, _, _ = ('1', '2', '3')
>>> a
'1'

星号 * 收集

类似函数的参数写法,用星号 * 可以收集剩余位置的元素。

>>> a, *others = ('1', '2', '3')
>>> a
'1'
>>> others
['2', '3']

因为 * 号是将当前对应位置的所有元素收集在一起,所以一次赋值中,不能出现多个星号 *

>>> a, *others, *another = ('1', '2', '3')
  File "<stdin>", line 1
SyntaxError: multiple starred expressions in assignment
>>>

但是星号* 可以出现在任意位置:

>>> a, *others, end = ('1', '2', '3', '4')
>>> a
'1'
>>> end
'4'
>>> others
['2', '3']
>>>

嵌套拆包

>>> a, (b, c), d = ('1',('2','3'),'4')
>>> a
'1'
>>> b
'2'
>>> c
'3'
>>> d
'4'
>>>

slicing 的哲学

序列(sequence)的切片操作(slicing) 在 这篇文章 里有介绍

[m:n) 的原因

最后一个元素是开区间,不包括在切片的结果里,比如

>>> ('1', '2', '3', '4')[:2]
('1', '2')

这样做的好处是:

  • 看出元素个数: [:n] 有 n个元素, [m:n] 有 n-m 个元素
  • 分成两部分:[:n][n:] 刚好是不重叠的两部分

列表的列表

如果想生成如下的一个列表(井字游戏的棋盘),该怎么写代码:

[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]

第一种:

>>> [['_'] * 3] * 3
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]

第二种:

>>> [['_'] * 3 for i in range(3)]
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]

看起来是一样的结果,但是第一种里三个list其实是同一个对象,如果修改其中任何一个,另外两个将同时被修改。

>>> wrong = [['_'] * 3] * 3
>>> wrong[0][2] = 'X'
>>> wrong
[['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']]
>>>

三个同时被修改。

而第二种的三次循环里生成了三个不同的对象,可以独立的修改而不相互影响。

>>> correct = [['_'] * 3 for i in range(3)]
>>> correct[0][2] = 'X'
>>> correct
[['_', '_', 'X'], ['_', '_', '_'], ['_', '_', '_']]
>>>

这篇文章 也提到过类似的事情。

序列的自增

可变序列普遍实现了自增:

list 的例子

>>> a=[1, 2]
>>> a+=[3]
>>> a
[1, 2, 3]
>>>

str 的例子

>>> a='abc'
>>> a+='d'
>>> a
'abcd'
>>>

列表的替代品

列表使用起来非常方便,但是在一些场合下并不是最优选择。

array

如果需要一个只包含数字的列表,那么 array.array 比 list 更高效。这里的高效,有时间和空间两个方面。

从一个二进制文件里读出1000万个double float只需要0.1秒,比文本文件快60倍

memoryview

memoryview 的概念和array类似,能用不同方式读写同一块内存数据,而且内容不会随意移动。

NumPy 和 SciPy

NumPy 提供了对高阶数组和矩阵的操作。

SciPy 则为线性代数、数值积分和统计学而设计。

deque

list.pop(0) 这种删除列表第一个元素的效率是很低的,因为会牵涉到移动列表的全部元素。deque 用来快速从两端添加或者删除元素的数据类型。

本章小结

要想写出准确、高效和地道的 Python 代码,掌握标准序列类型(sequence)是不可或缺的。

序列可以分为可变、不可变两类,也可以分为扁平和容器型两类。容器序列遇到可变对象时就要额外小心,这两种组合容易搞出一些意外。

列表推导和生成器并不难,而且用起来使人上瘾。

元组 tuple 扮演了两类角色,即可以用作无名称字段的记录,有可以看作不可变的列表。

元组的拆包赋值是最安全、可靠的提取字段信息的方法。

除了列表和元组,标准库里还有 array.array、collections.deque 等类型。

杂谈

元组的本质

Practicality beats purity. 实用胜过纯粹。

ABC 语言里的 compounds 类是 Python 元组的鼻祖,但是compounds 不属于序列,不是 iterable,不能通过下标取值,不能 slicing。要么当做整体来用,要么通过平行赋值把所有字段取出来。compounds 是个纯粹的设计,然而 Python 的 tuple 更为实用。这体现:

优雅和简约

Elegance begets simplicity. 优雅是简约之父

*extra 这种语法将多个元素赋值给一个参数,并且取代了 Python 里的 apply 函数。如今到了 Python3 里,又可以用在赋值表达式的左侧,这让本来就很实用的语法锦上添花。

这样的改进让 Python 变得越来越灵活,越来越统一。

key参数

list.sort、sorted、max 和 min 函数的 key 参数是个很棒的设计。其他语言里的排序函数需要用户提供双参数的函数,例如 cmp(a, b),简单而高效。

说它简单,是因为只需要提供一个单参数的函数即可。说它高效,是因为在每个元素上,key 函数只会被调用一次。

另外,key 函数也能让你对一个混合序列排序:

>>> l = ['28',14,'5']
>>> sorted(l, key=str)
[14, '28', '5']
>>> sorted(l, key=int)
['5', 14, '28']
>>>

关于 Tim 的八卦

sorted 和 list.sort 背后的排序算法是 Timsort,它是一种自适应算法,根据原始数据的顺序特点交替使用插入排序和归并排序。

Timsort 的作者是 Tim Peters,是一位高产的 Python 核心开发者,同时也是 Python 之禅(import this)的作者。

s = """Gur Mra bs Clguba, ol Gvz Crgref
Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""

d = {}
for c in (65, 97):
    for i in range(26):
        d[chr(i+c)] = chr((i+13) % 26 + c)

print("".join([d.get(c, c) for c in s]))

各位读后有什么想法,请在下方留言吧!如果对本文有疑问或者寻求合作,欢迎 联系邮箱邮箱已到剪贴板

精彩评论