Python进阶1-元组和列表

本系列文章是一系列学习笔记,希望较为深入地分析Python3中的原理、性能,文章中绝大部分观点都是原作作者的观点(如下),本人对书中示例加以实践和总结,并结合相应的Python的C语言源码(3.6.1),分享出来。原著:

  • 《High Performance Python》by O'Relly Media,作者Micha Gorelick,Ian Ozsvald
  • 《Fluent Python》by O'Relly Media,作者Luciano Ramalho

深入理解各种序列(元组、列表等)能阻止我们不要重复造轮子。

序列的分类

常见的分类一般按照Mutable和Immutable分类,还可以按照:
Container sequence(元素为对象的序列):List,Tuple,collections.deque
Flat sequence(紧凑序列):str,bytes,bytearray,memoryview,array.array

列表List

List:动态数组,元素可变,可改变大小(append,resize)
列表是很容易掌握的,说一些重点的操作。

列表推导(List Comprehensions)和生成器(Generator)

列表推导和生成器是创建列表和其他序列的快速方法,能够写出简介且高性能的代码。

>>> dummy = [x for x in 'ABC']
>>> dummy
['A', 'B', 'C']

map和filter也能快速创建列表,但是在性能上并没有优势:

(env) MengdeiMac:02-array-seq an$ cat listcomp_speed.py 
import timeit

TIMES = 10000

SETUP = """
symbols = '$¢£¥€¤'
def non_ascii(c):
    return c > 127
"""

def clock(label, cmd):
    res = timeit.repeat(cmd, setup=SETUP, number=TIMES)
    print(label, *('{:.3f}'.format(x) for x in res))

clock('listcomp        :', '[ord(s) for s in symbols if ord(s) > 127]')
clock('listcomp + func :', '[ord(s) for s in symbols if non_ascii(ord(s))]')
clock('filter + lambda :', 'list(filter(lambda c: c > 127, map(ord, symbols)))')
clock('filter + func   :', 'list(filter(non_ascii, map(ord, symbols)))')
(env) MengdeiMac:02-array-seq an$ python listcomp_speed.py 
listcomp        : 0.012 0.013 0.013
listcomp + func : 0.017 0.018 0.032
filter + lambda : 0.020 0.016 0.025
filter + func   : 0.015 0.020 0.025

创建元组、arrays等序列时,也可以通过列表推导来做,但是使用生成器可以更加节省内存。(通过iterator protocal生成元素,而不是全部生成放在内存里)

元组Tuple

** 元组不仅仅是“不可修改的列表”(Immutable List)**
** 元组也可以被用作“无属性的记录”(Records with no field name)**

Tuple as Records

如果只是把元组看作不可变的列表,那么元素的顺序并不是很重要。我们可以把元组看作一系列的属性,属性的数量是固定的,位置也是重要的。

(name, age)  = ('Jack', 18)

我们可以通过位置获取相应的属性,书中还介绍了Named Tuple,collections .nametuple,可以赋予属性名字,可以通过名字或位置来访问属性,比Object更轻量。

Tuple as Immutable List

Tuple支持所有的List的方法,除了add,delete,reverse。
每一个Python程序员都知道,序列可以切片,像这样a[start:stop],一些不那么出名知识点。

为什么slice和range不包括最后一个元素

  • 这样更容易得到slice的长度 = stop - start
  • 更容易将序列分割成两个部分,a[:3]和a[3:]
 >>> a = [1,2,3,4,5]
>>> a[:3]
[1, 2, 3]
>>> a[3:]
[4, 5]

序列的赋值+=, *=

+= 依赖iadd的实现,也就是inplace addition
*= 依赖imul的实现
对于可变序列(List),inplace的操作都实现的很好,对于不可变序列(Tuple),没有实现。

>>> l=[1,2,3]
>>> id(l)
4322512072
>>> l *= 2
>>> l
[1, 2, 3, 1, 2, 3]
>>> id(l)
4322512072
>>> 
>>> 
>>> t=(1,2,3)
>>> id(t)
4322621768
>>> t *= 2
>>> t
(1, 2, 3, 1, 2, 3)
>>> id(t)
4322550888
>>> 

也就是,对于一个不可变序列, 重复的粘贴操作是非常低效的,伴有很多的内存分配和拷贝操作。
还有一个corner case,想想输出是为什么?既抛出异常,tuple也被改变了,结论就是,不要让tuple中有可变的对象,叠加赋值操作不是原子操作。

>>> l=(1,2,[30,50])
>>> l[2] += [50,60]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> l
(1, 2, [30, 50, 50, 60])
>>> 

list.sort vs sort

有两个排序函数:
列表自带的函数,list.sort,对一个列表进行原地排序,也就是,不生成一个新的拷贝。
内置的sort函数,sort,创建一个新的列表,排序,并且返回新列表。

还有一点重要的常识:
functions or methods that change an object in place should return None to make it clear to the caller that the object itself was changed, and no new object was created.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容