前言
强烈推荐一本书《Python Cookbook》未来Python笔记算是读此书时候带来的收获。学而不思则罔,用而不思则迷。此书尤其适合有一定开发经验的读者,能完善技能。总结过程中,会对着2.x和3.x版本之间一些区别。
本节主要梳理 list,dict基本方法以及在2.x和3.x版本之间一些区别,mutable和hashable的概念,解压赋值,个别小技巧。
数据结构
python基础数据类型有哪些?int, float, str, tuple, list, dict, set,简单梳理梳理list, dict。
list
相比tuple,list可以修改,对于list的创建和遍历不在赘述,
基础方法有如下。
list 内置方法
l = list()
l.append(element)
l.pop([index]) # 弹出索引位置元素,缺省弹出最后一位,会出越界异常
l.insert(index, element) # 索引位插入元素,超出长度插在末尾,注意append的复杂度是 1,但insert的复杂度是 n
l.extent(element_list) # 拓展列表,拼接列表
l.count(element) # 统计元素数量
l.index(element) # 查找元素首次出现索引,未找到抛异常
l.sort() # 排序列表,无返回值
l.reverse() #倒序列表
list切片
list有类似字符串的切片功能,具体用法:
# 基础用法
new_l = l[start:end:step]
# cookbook中给出的一个关于切片命名示例,提高程序可读性 0123456789012345678901234567890123456789012345678901234567890
record = '....................100 .......513.25 ..........'
cost = int(record[20:23]) * float(record[31:37])
# 优化写法
SHARES = slice(20, 23)
PRICE = slice(31, 37)
cost = int(record[SHARES]) * float(record[PRICE])
注意:切片返回的对象是新生成的,即使new_l == l 为Ture 但 new_l is l 返回false。说白了new_l 和 l 指向不同的内存空间。
dict
数据结构字典是最为常用的数据类型,其中包括了很多内置方法,不仅如此2.x和3.x中对于字典改动较大,而且是无感知改动。
dict内置方法
del(d["a"]) # 删除字典中存在的 “a” 键值对,无返回
d.pop("a") # 删除字典中存在的 “a” 键值对,“a”不存在抛异常
d.update(d2) # 更新d2到d中
dict(d, **d1) # 合并d, d1生成新字典
d.setdefault('e', []) # 更新d添加e对应value是[],并返回 d['e']
字典还有很多方法2.x和3.x返回数据类型不同:
# python 2.x
type(d.keys()) # <type 'list'>
type(d.values()) # <type 'list'>
type(d.items()) # <type 'list'>
type(d.iteritems()) # <type 'dictionary-itemiterator'>
# python 3.x
type(d.keys()) # <class 'dict_keys'>
type(d.values()) # <class 'dict_keys'>
type(d.items()) # <class 'dict_items'>
# 3.x 无 d.iteritems()方法
可以看出在python3中对字典的keys,values,items内置方法都进行了封装,由原来简单的list类型变成了对应的字典数据类型,因此拓展出一些在python3中有的运用方法
# python 3.x
a={'x' : 1, 'y' : 2, 'z' : 3}
b={'w' : 10, 'x' : 11, 'y' : 2}
# 两字典公共key的交集
a.keys() & b.keys() # { 'x', 'y' }
# a字典对b字典的差集
a.keys() - b.keys() # { 'z' }
# a字典和b字典 items结果的并集
b.items() | { ('y', 2) }
高级字典
在出dict类型外还有几种高级字典的数据类型在内置包 collections 中,包括defaultdict,OrderedDict
from collections import defaultdict, OrderedDict
dd = defaultdict(list) # 默认值为list的字典
dd['test_key'].append(1) # 直接给'test_key'的值进行元素扩展
od = OrderedDict() # od是有序字典
od['y'] = 1
od['z'] = 2
od['x'] = 3
od.keys() # ['y', 'z', 'x']
od.values() # [1, 2, 3]
collections还有其他的数据类型如namedtuple, deque, Counter,具体使用留个看官自行查询。
mutable 和 hashable
python中有一个数据概念 mutable 和 immutable。曾经被问起python基础数据类型中,什么样的是不可变的?第一反应tuple因为于list相比明显区别的性质,除此之外呢?就python基础数据类型而言,int,float也是不可变的。
str呢?试想str_test[index]形式调用一额str类型的某一个索引的字符,是不是可以通过str_test[index]=somevalue进行赋值?答案是否定的!因为str是字符串常量,就像tuple可以通过index取,但不可以对index位置修改赋值。
综上int, float, str, tuple四种类型的数据都是生成后不可变的,immutable的。而剩下的list, dict, set是可变的mutable。
hashable直译理解就是“哈希化”。python字典数据类型低层存储结构是“哈希表”,key-value形势。真正的index是对key运用哈希函数计算得出,所以要求key值必须是不可变的值作为key,由此可以看出,在python中所有immutable数据类型都可以作为dict的key,相对而言immutable的值是hashable的。
解压赋值
实例说明:
# python 2.x
a, b = [1, 3] # a=1, b=3
a, *b = [1, 3, 5] # 异常
# python 3.x
a, *b = [1, 3, 5] # a=1, b=[3, 5]
这种赋值方式初看觉得花哨,实则很是有用,通常在函数定义时会有可变参数,参照类比理解
# 常见函数定义形如
# args可以是list,tuple解压批量赋值,kwargs可以用dict解压批量复制
def func(*args, **kwargs):
pass
上文的字典合并,就是将d1赋值给了kwargs。
实用技巧
解析
非常实用的是列表解析,效率比for快一倍,能够用列表解析完成功能的地方推荐使用,此外还有字典解析:
b_list = [x for x in a_list if condition else ret2]
b_dict = {key: value for key, value in a_dict.items() if condition}
sum妙用
sum(iterable_param) python内置求和函数
sum([1, 2, 3])
# 妙用完成双层列表展开成单层
sum([[1, 5], [2, 3]], []) # 结果 [1, 5, 2, 3]