3.1 数据结构和序列
元组
元组是一个固定长度,不可改变的Python序列对象。圆括号。
用tuple可以将任意序列或迭代器转换成元组:
可以用方括号访问元组中的元素。序列是从0开始的:
元组中存储的对象可能是可变对象。一旦创建了元组,元组中的对象就不能修改了:
tuple方法
因为元组的大小和内容不能修改,count方法(也适用于列表)可以统计某个值得出现频率:
In [34]: a = (1, 2, 2, 2, 3, 4, 2)
In [35]: a.count(2)
Out[35]: 4
列表
与元组对比,列表的长度可变、内容可以被修改。你可以用方括号定义,或用list函数
list函数常用来在数据处理中实体化迭代器或生成器:
用append在列表末尾添加元素:b_list.append('dwarf')
insert可以在特定的位置插入元素:b_list.insert(1, 'red')
插入的序号必须在0和列表长度之间。
insert的逆运算是pop,它移除并返回指定位置的元素:b_list.pop(2)
用remove去除某个值,remove会先寻找第一个值并除去:
用in可以检查列表是否包含某个值:'dwarf' in b_list
否定in可以再加一个not:'dwarf' not in b_list
在列表中检查是否存在某个值远比字典和集合速度慢
串联和组合列表
与元组类似,可以用加号将两个列表串联起来:[4, None, 'foo'] + [7, 8, (2, 3)]
用extend方法可以追加多个元素: x.extend([7, 8, (2, 3)])
通过加法将列表串联的计算量较大,因为要新建一个列表,并且要复制对象。用extend追加元素比串联方法快。
排序
用sort函数将一个列表原地排序(不创建新的对象): a.sort()对数字
sort的二级排序key很好用,例如,我们可以按长度对字符串进行排序:b.sort(key=len)
二分搜索和维护已排序的列表
bisect模块支持二分查找,和向已排序的列表插入值。
bisect.bisect可以找到插入值后仍保证排序的位置,bisect.insort是向这个位置插入值: bisect.bisect(c, 2),bisect.insort(c, 6)
注意:bisect模块不会检查列表是否已排好序,进行检查的话会耗费大量计算。因此,对未排序的列表使用bisect不会产生错误,但结果不一定正确。
切片
用切边可以选取大多数序列类型的一部分,切片的基本形式是在方括号中使用start:stop:step
在第二个冒号后面使用的step,指隔step取一个元素:seq[::2]
step=-1可以将列表或元组颠倒过来:seq[::-1]
序列函数
enumerate函数可以返回(i, value)元组序列来跟踪当前项的序号:for i, value in enumerate(collection):
sorted函数可以从任意序列的元素返回一个新的排好序的列表:sorted([7, 1, 2, 6, 0, 3, 2])。sorted函数可以接受和sort相同的参数。
zip可以将多个列表、元组或其它序列成对组合成一个元组列表:zipped = zip(seq1, seq2)
zip可以处理任意多的序列,元素的个数取决于最短的序列:
zip的常见用法之一是同时迭代多个序列,可能结合enumerate使用:for i, (a, b) in enumerate(zip(seq1, seq2)):
给出一个“被压缩的”序列,zip可以被用来解压序列。也可以当作把行的列表转换为列的列表:first_names, last_names = zip(*pitchers)
reversed函数可以从后向前迭代一个序列:list(reversed(range(10)))
字典
更为常见的名字是哈希映射或关联数组。。它是键值对的大小可变集合,键和值都是Python对象。创建方法:尖括号,用冒号分隔键和值: empty_dict = {},d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}
像访问列表或元组中的元素一样,访问、插入或设定字典中的元素:d1[7] = 'an integer',d1['b']
用检查列表和元组是否包含某个值得方法,检查字典中是否包含某个键:'b' in d1
用del关键字或pop方法(返回值得同时删除键)删除值:
keys和values是字典的键和值的迭代器方法。虽然键值对没有顺序,这两个方法可以用相同的顺序输出键和值:
In [117]: list(d1.keys())
Out[117]: ['a', 'b', 7]
In [118]: list(d1.values())
Out[118]: ['some value', [1, 2, 3, 4], 'an integer']
用update方法可以将一个字典与另一个融合:d1.update({'b' : 'foo', 'c' : 12})
update方法是原地改变字典,因此任何传递给update的键的旧的值都会被舍弃。
默认值
dict的方法get和pop可以取默认值进行返回:value = some_dict.get(key, default_value)
get默认会返回None,如果不存在键,pop会抛出一个例外。
setdefault方法:
for word in words:
letter = word[0]
by_letter.setdefault(letter, []).append(word)
有效的键类型
字典的值可以是任意Python对象,而键通常是不可变的标量类型(整数、浮点型、字符串)或元组(元组中的对象必须是不可变的)。这被称为“可哈希性”。可以用hash函数检测一个对象是否是可哈希的(可被用作字典的键):hash('string')
要用列表当做键,一种方法是将列表转化为元组,只要内部元素可以被哈希,它也就可以被哈希: d[tuple([1, 2, 3])] = 5
集合
集合是无序的不可重复的元素的集合。你可以把它当做字典,但是只有键没有值。可以用两种方式创建集合:通过set函数或使用尖括号set语句:
In [133]: set([2, 2, 2, 1, 3, 3])
Out[133]: {1, 2, 3}
In [134]: {2, 2, 2, 1, 3, 3}
Out[134]: {1, 2, 3}
用union方法或者|运算符可以取两个集合中不重复的元素: a.union(b) ,a | b
与字典类似,集合元素通常都是不可变的。要获得类似列表的元素,必须转换成元组: my_set = {tuple(my_data)}
你还可以检测一个集合是否是另一个集合的子集或父集:{1, 2, 3}.issubset(a_set)
集合的内容相同时,集合才对等,因为是无序的所以顺序可以不同:
列表、集合和字典推导式
列表推导式允许用户方便的从一个集合过滤元素,形成列表,在传递参数的过程中还可以修改元素。形式如下:
[expr for val in collection if condition]
等同于下面的for循环;
result = []
for val in collection:
if condition:
result.append(expr)
给定一个字符串列表,我们可以过滤出长度在2及以下的字符串,并将其转换成大写:
In [154]: strings = ['a', 'as', 'bat', 'car', 'dove', 'python'] In [155]: [x.upper() for x in strings if len(x) > 2] Out[155]: ['BAT', 'CAR', 'DOVE', 'PYTHON']
字典的推导式如下所示:dict_comp = {key-expr : value-expr for value in collection if condition}
集合的推导式用的是尖括号:set_comp = {expr for value in collection if condition}
假如我们只想要字符串的长度,用集合推导式的方法非常方便:
In [156]: unique_lengths = {len(x) for x in strings}
In [157]: unique_lengths
Out[157]: {1, 2, 3, 4, 6}
用map函数可以进一步简化:set(map(len, strings))
我们可以创建一个字符串的查找映射表以确定它在列表中的位置:
loc_mapping = {val : index for index, val in enumerate(strings)}
3.2 函数
函数使用def关键字声明,用return关键字返回值:
关键字参数通常用于指定默认值或可选参数。关键字参数必须位于位置参数(如果有的话)之后。你可以任何顺序指定关键字参数。
命名空间、作用域,和局部函数
任何在函数中赋值的变量默认都是被分配到局部命名空间(local namespace)中的。局部命名空间是在函数被调用时创建的,函数参数会立即填入该命名空间。在函数执行完毕之后,局部命名空间就会被销毁
可以在函数中对全局变量进行赋值操作,但是那些变量必须用global关键字声明成全局的才行:
注意:我常常建议人们不要频繁使用global关键字。因为全局变量一般是用于存放系统的某些状态的。如果你发现自己用了很多,那可能就说明得要来点儿面向对象编程了(即使用类)。
返回多个值
return a, b, c
return {'a' : a, 'b' : b, 'c' : c}
生成器
能以一种一致的方式对序列进行迭代(比如列表中的对象或文件中的行)是Python的一个重要特点。这是通过一种叫做迭代器协议(iterator protocol,它是一种使对象可迭代的通用方式)的方式实现的,一个原生的使对象可迭代的方法。比如说,对字典进行迭代可以得到其所有的键:
In [180]: some_dict = {'a': 1, 'b': 2, 'c': 3}
In [181]: for key in some_dict:
.....: print(key)
a
b
c
当你编写for key in some_dict时,Python解释器首先会尝试从some_dict创建一个迭代器:
In [182]: dict_iterator = iter(some_dict)
In [183]: dict_iterator
Out[183]:
作者:SeanCheney
链接:https://www.jianshu.com/p/b444cda10aa0
來源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。