《Python从小白到大牛》已经上市!
当你有不少书时,你会考虑买一个书柜,将你的书分门别类摆放进入。使用了书柜不只仅使房间变得整洁,也便于之后使用书时方便查找。在计算机程序中会有不少数据,这些数据也须要一个容器将他们管理起来,这就是数据结构。常见的数据结构:数组(Array)、集合(Set)、列表(List)、队列(Queue)、链表(Linkedlist)、树(Tree)、堆(Heap)、栈(Stack)和字典(Dictionary)等结构。html
Python中数据容器主要有:序列、集合和字典。python
注意
Python中并无数组结构,由于数组要求元素类型是一致的。而Python做为动态类型语言,不强制声明变量的数据类型,也不能强制检查元素的数据类型。因此Python中没有数组结构。shell
元组(tuple)是一种序列(sequence)结构,下面先来介绍一些序列。express
序列(sequence)是一种可迭代的^1,元素是有序的,能够重复出现的数据结构。序列能够经过索引访问元素。图9-1是一个班级序列,其中有一些学生,这些学生是有序的,顺序是他们被放到序列中的顺序,能够经过序号访问他们。这就像老师给进入班级的人分配学号,第一个报到的是“张三”,老师给他分配的是0,第二个报到的是“李四”,老师给他分配的是1,以此类推,最后一个序号应该是“学生人数-1”。数组
序列包括的结构有:列表(list)、字符串(str)、元组(tuple)、范围(range)、和字节序列(bytes)。序列可进行的操做有:索引、分片、加和乘。微信
序列中第一个元素的索引是0,其余元素的索引是第一个元素的偏移量。能够有正偏移量,称为正值索引;也能够有负偏移量,称为负值索引。正值索引最后一个元素索引是“序列长度-1”,负值索引最后一个元素索引是“-1”。例如Hello字符串,它的正值索引如图9-2(a)所示,它的负值索引如图9-2(b)所示。数据结构
访问序列中的元素的经过索引下标访问的,即中括号[index]方式访问。在Python
Shell中运行示例以下:app
>>> a = 'Hello' >>> a[0] 'H' >>> a[1] 'e' >>> a[4] 'o' >>> a[-1] 'o' >>> a[-2] 'l' >>> a[5] Traceback (most recent call last): File "<pyshell#2>", line 1, in <module> a[5] IndexError: string index out of range >>> max(a) 'o' >>> min(a) 'H' >>> len(a) 5
a[0]是访问序列第一个元素,最后一个元素的索引能够是4或-1。可是索引超过范围,则会发生IndexError错误。另外,获取序列的长度使用函数len,相似的序列还有max和min函数,max函数返回最后一个元素,min函数返回第一个元素。 ide
下面看看序列的加和乘,在前面第7章介绍+和*运算符时,提到过他们能够应用于序列。+运算符能够将两个序列链接起来,*运算符能够将重复屡次。函数
在Python Shell中运行示例:
>>> a = 'Hello' >>> a * 3 'HelloHelloHello' >>> print(a) Hello >>> a += ' ' >>> a += 'World' >>> print(a) Hello World
序列的分片(Slicing)就是从序列中切分出小的子序列。分片使用分片运算符,分片运算符有两种形式:
[start:end]。start是开始索引,end是结束索引。
注意
切下的分片包括start位置元素,但不包括end位置元素,start和end均可以省略。
在Python Shell中运行示例代码以下:
>>> a[1:3] 'el' >>> a[:3] 'Hel' >>> a[0:3] 'Hel' >>> a[0:] 'Hello' >>> a[0:5] 'Hello' >>> a[:] 'Hello' >>> a[1:-1] 'ell'
上述代码表达式a[1:3]是切出1\~3之间的子字符串,注意不包括3,因此结果是el。表达式a[:3]省略了开始索引,默认开始索引是0,因此a[:3]与a[0:3]分片结果是同样的。表达式a[0:]省略告终束索引,默认结束索引是序列的长度,即5。因此a[0:]
与a[0:5]分片结果是同样的。表达式a[:]是省略了开始索引和结束索引,a[:]与a[0:5]结果同样。
另外,表达式a[1:-1]使用了负值索引,对照图9-1所示,不难计算出a[1:-1]结果是ell。
分片时使用[start:end:step]能够指定步长(step),步长与当次元素索引、下次元素索引之间的关系以下:
> 下次元素索引 = 当次元素索引 + 步长
在Python Shell中运行示例代码以下:
>>> a[1:5] 'ello' >>> a[1:5:2] 'el' >>> a[0:3] 'Hel' >>> a[0:3:2] 'Hl' >>> a[0:3:3] 'H' >>> a[::-1] 'olleH'
表达式a[1:5]省略了步长参数,步长默认值是1。表达式a[1:5:2]是步长为2,结果是el。a[0:3]分片后的字符串是Hel。而a[0:3:3]是步长为3,分片结果H字符了。当步长为负数时比较麻烦,负数时是从右往左获取元素,因此表达式a[::-1]分片的结果是原始字符串的倒置。
元组(tuple)是一种不可变序列,一旦建立就不能修改。建立元组可使用tuple([iterable])函数或者直接用逗号(,)将元素分隔。
在Python Shell中运行示例代码以下:
>>> 21,32,43,45 ① (21, 32, 43, 45) >>> (21, 32, 43, 45) ② (21, 32, 43, 45) >>> a = (21,32,43,45) >>> print(a) (21, 32, 43, 45) >>> ('Hello', 'World') ③ ('Hello', 'World') >>> ('Hello', 'World', 1,2,3)④ ('Hello', 'World', 1, 2, 3) >>> tuple([21,32,43,45]) ⑤ (21, 32, 43, 45)
代码第①行建立了一个有4个元素的元组,建立元组时使用小括号把元素包裹起来不是必须的。代码第②行使用括号将元素包裹起来,这只是为了提升程序的可读性。Python中没有强制声明数据类型,所以元组中的元素能够是任何数据类型,代码第③行建立是一个字符串元组,代码第④行是建立字符串和整数混合的元组。
另外,元组还有经过tuple([iterable])函数建立,参数iterable是任何可迭代对象。代码第⑤行是使用tuple()函数建立元组对象,实参[21,32,43,45]是一个列表,列表是可迭代对象,能够做为tuple()函数参数建立元组对象。
建立元组还须要注意以下极端状况:
>>> a = (21) >>> type(a) <class 'int'> >>> a = (21,) >>> type(a) <class 'tuple'> >>> a = () >>> type(a) <class 'tuple'>
从上述代码可见,若是一个元组只有一个元素时,后面的逗号不能省略,即(21,)表示的是只有一个元素的元组,而(21)表示的是一个整数。另外,()能够建立空元组。
元组作为序列能够经过下标索引访问元素,也能够对其进行分片。在Python
Shell中运行示例代码以下:
>>> a = ('Hello', 'World', 1,2,3) ① >>> a[1] 'World' >>> a[1:3] ('World', 1) >>> a[2:] (1, 2, 3) >>> a[:2] ('Hello', 'World')
上述代码第①行是元组a,a[1]是访问元组第二个元素,表达式a[1:3]、a[2:]和a[:2]都是进行分片操做。
元组还能够进行拆包(Unpack)操做,就是将元组的元素取出赋值给不一样变量。在Python Shell中运行示例代码以下:
>>> a = ('Hello', 'World', 1,2,3) >>> str1, str2, n1,n2, n3 = a ① >>> str1 'Hello' >>> str2 'World' >>> n1 1 >>> n2 2 >>> n3 3 >>> str1, str2, *n = a ② >>> str1 'Hello' >>> str2 'World' >>> n [1, 2, 3] >>> str1,_,n1,n2,_ = a ③
上述代码第①行是将元组a进行拆包操做,接收拆包元素的变量个数应该等于元组个数相同。接收变量个数也能够少于元组个数,代码第②行接收变量个数只有3个,最后一个很特殊,变量n前面有星号,表示将剩下的元素做为一个列表赋值给变量n。另外,还可使用下划线指定哪些元素不取值,代码第行是不取第二个和第五个元素。
遍历元组通常是使用for循环,示例代码以下:
# coding=utf-8 # 代码文件:chapter9/ch9.1.4.py a = (21, 32, 43, 45) for item in a: ① print(item) print('-----------') for i, item in enumerate(a): ② print('{0} - {1}'.format(i, item))
输出结果以下:
21 32 43 45 ----------- 0 - 21 1 - 32 2 - 43 3 – 45
通常状况下遍历目的只是取出每个元素值,见代码第①行的for循环。但有时须要在遍历过程当中同时获取索引,则可使用代码第②行的for循环,其中enumerate(a)函数能够得到元组对象,该元组对象有两个元素,第一个元素是索引,第二个元素是数值。因此i,
item是元组拆包过程,最后变量i是元组a的当前索引,item是元组a的当前元素值。
注意
本节虽然介绍的是元组的遍历,上述遍历方式适合于全部序列,如字符串、范围和列表等。
列表(list)也是一种序列结构,与元组不一样列表具备可变性,能够追加、插入、删除和替换列表中的元素。
建立列表可使用list([iterable])函数,或者用中括号[]将元素包裹,元素之间用逗号分隔。在Python Shell中运行示例代码以下:
>>> [20, 10, 50, 40, 30] ① [20, 10, 50, 40, 30] >>> [] [] >>> ['Hello', 'World', 1, 2, 3] ② ['Hello', 'World', 1, 2, 3] >>> a = [10] ③ >>> type(a) <class 'list'> >>> a = [10,] ④ >>> type(a) <class 'list'> >>> list((20, 10, 50, 40, 30)) ⑤ [20, 10, 50, 40, 30]
上述代码第①行建立一个有5个元素的列表,注意中括号不能省略,若是省略了中括号那就变成了元组了。建立空列表是[]表达式。列表中能够放入任何对象,代码第②行是建立一个字符串和整数混合的列表。代码第③行是建立只有一个元素的列表,中括号不能省略。另外,不管是元组仍是列表,每个元素后面都跟着一个逗号,只是最后一个元素的逗号常常是省略的,代码第④行最后一个元素没有省略逗号。
另外,列表还有经过list([iterable])函数建立,参数iterable是任何可迭代对象。代码第⑤行是使用list()函数建立列表对象,实参(20,
10, 50, 40,
30)是一个元组,元组是可迭代对象,能够做为list()函数参数建立列表对象。
列表中追加单个元素可使用append()方法追加单个元素。若是想追加另外一列表,可使用+运算符或extend()方法。
append()方法语法:
list.append(x)
其中x参数是要追加单个元素值。
extend()方法语法:
list.extend(t)
其中t参数是要追加的另一个列表。
在Python Shell中运行示例代码以下:
>>> student_list = ['张三', '李四', '王五'] >>> student_list.append('董六') ① >>> student_list ['张三', '李四', '王五', '董六'] >>> student_list += ['刘备', '关羽'] ② >>> student_list ['张三', '李四', '王五', '董六', '刘备', '关羽'] >>> student_list.extend(['张飞', '赵云']) ③ >>> student_list ['张三', '李四', '王五', '董六', '刘备', '关羽', '张飞', '赵云']
上述代码中第①行使用了append方法,在列表后面追加一个元素,append()方法不能同时追加多个元素。代码第②行是利用+=运算符追加多个元素,可以支持+=运算是由于列表支持+运算。代码第③行是使用extend()方法追加多个元素。
插入元素可使用列表的insert()方法,该方法能够在指定索引位置,插入一个元素。insert()方法语法:
list.insert(i, x)
其中参数i是要插入的索引,参数x是要插入的元素数值。
在Python Shell中运行示例代码以下:
>>> student_list = ['张三', '李四', '王五'] >>> student_list.insert(2, '刘备') >>> student_list ['张三', '李四', '刘备', '王五']
上述代码中student_list调用insert方法,在索引2位置插入一个元素,新元素的索引为2。
列表具备可变性,其中的元素替换,替换元素很简单,经过列表下标索引元素放在赋值符号(=)左边,进行赋值便可替换。在Python
Shell中运行示例代码以下:
>>> student_list = ['张三', '李四', '王五'] >>> student_list[0] = "诸葛亮" >>> student_list ['诸葛亮', '李四', '刘备', '王五']
其中student_list[0] = "诸葛亮"是替换列表student_list的第一个元素。
列表中实现删除元素的方式有两种:一种是使用列表的remove()方法;另外一种是使用列表的pop()方法。
remove()方法从左往右查找列表中的元素,若是找到匹配元素则删除,注意若是找到多个匹配元素,只是删除第一个。若是没有找到则会抛出错误。
remove()方法语法:
list.remove(x)
其中x参数是要找到元素值。
使用remove()方法删除元素,示例代码以下:
>>> student_list = ['张三', '李四', '王五', '王五'] >> student_list.remove('王五') >>> student_list ['张三', '李四', '王五'] >>> student_list.remove('王五') >>> student_list ['张三', '李四']
pop()方法也会删除列表中的元素,但它会将成功删除的元素返回。pop()方法语法以下:
item = list.pop([i])
参数i是指定删除元素的索引,i能够省略,表示删除最后一个元素。返回值item是删除的元素。
使用pop()方法删除元素示例代码以下:
>>> student_list = ['张三', '李四', '王五'] >>> student_list.pop() '王五' >>> student_list ['张三', '李四'] >>> student_list.pop(0) '张三' >>> student_list ['李四']
前面介绍列表追加、插入和删除时,已经介绍了一些方法。事实上列表还有不少方法,本节再介绍几个经常使用的方法。包括:
reverse()。倒置列表。
copy()。复制列表。
clear()。清除列表中的全部元素。
index(x[, i[,
j]])。返回查找x第一次出现的索引,i是开始查找索引,j是结束查找索引。该方法继承自序列,元组和字符串也可使用该方法。
在Python Shell中运行示例代码以下:
>>> a = [21, 32, 43, 45] >>> a.reverse() ① >>> a [45, 43, 32, 21] >>> b = a.copy() ② >>> b [45, 43, 32, 21] >>> a.clear() ③ >>> a [] >>> b [45, 43, 32, 21] >>> a = [45, 43, 32, 21, 32] >>> a.count(32) ④ 2 >>> student_list = ['张三', '李四', '王五'] >>> student_list.index('王五') ⑤ 2 >>> student_tuple = ('张三', '李四', '王五') >>> student_tuple.index('王五') ⑥ 2 >>> student_tuple.index('李四', 1 , 2) 1
上述代码中第①行是调用reverse()方法将列表a倒置。代码第②行是调用copy()方法复制a,并赋值给b。代码第③行是清除a中元素。代码第④行是返回a列表中32元素的个数。代码第⑤行是返回'王五'在student_list列表中的位置。代码第⑥行是返回'王五'在student_tuple元组中的位置。
Python中有一种特殊表达式——推导式,它能够将一种数据结构做为输入,通过过滤、计算等处理,最后输出另外一种数据结构。根据数据结构的不一样分为:列表推导式、集合推导式和字典推导式。本节先介绍列表推导式。
若是想得到0\~9中偶数的平方数列,那么能够经过for循环实现,代码以下:
# coding=utf-8 # 代码文件:chapter9/ch9.2.7.py n_list = [] for x in range(10): if x % 2 == 0: n_list.append(x ** 2) print(n_list)
输出结构以下:
[0, 4, 16, 36, 64]
0\~9中偶数的平方数列能够经过列表推导式实现,代码以下:
n_list = [x ** 2 for x in range(10) if x % 2 == 0] ① print(n_list)
上述代码其中代码第行就是列表推导式,输出的结果与for循环是同样的。图9-3所示是列表推导式语法结构,其中in后面的表达式是“输入序列”;for前面的表达式是“输出表达式”它运算结果会保存一个新列表中;if条件语句是过滤输入序列,符合条件的才传递给输出表达式,“条件语句”是能够省略的,也是全部元素都传递给输出表达式。
条件语句能够包含多个条件,若是想找出0\~99之间的偶数,并且能够被5整除数列,实现代码以下:
n_list = [x for x in range(100) if x % 2 == 0 if x % 5 == 0] print(n_list)
列表推导式的条件语句有两个if x % 2 == 0和if x % 5 == 0,可见他们“与”的关系。
集合(set)是一种可迭代的、无序的、不能包含重复元素的数据结构。图9-4是一个班级的集合,其中包含一些学生,这些学生是无序的,不能经过序号访问,并且不能有重复的同窗。
提示
若是与序列比较,序列中的元素是有序的,能够重复出现,而集合中是无序的,不能重复的元素。序列强调的是有序,集合强调的是不重复。当不考虑顺序,并且没有重复的元素时,序列和集合能够互相替换。
集合又分为可变集合(set)和不可变集合(frozenset)。
可变集合类型是set,建立可变集合可使用set([iterable])函数,或者用大括号{}将元素包裹,元素之间用逗号分隔。在Python
Shell中运行示例代码以下:
>>> a = {'张三', '李四', '王五'} ① >>> a {'张三', '李四', '王五'} >>> a = {'张三', '李四', '王五', '王五'}② >>> len(a) 3 >>> a {'张三', '李四', '王五'} >>> set((20, 10, 50, 40, 30)) ③ {40, 10, 50, 20, 30} >>> b = {} ④ >>> type(b) <class 'dict'> >>> b = set() ⑤ >>> type(b) <class 'set'>
上述代码第①行是使用大括号建立集合,若是元素有重复的会怎样呢?代码第②行包含有重复的元素,建立时会剔除重复元素。代码第③行是使用set()函数建立集合对象。若是要建立一个空的集合不能使用{}表示,见代码第④行b并非集合而是字典,而是使用空参数的set()函数,见代码第⑤行。
提示
要得到集合中元素的个数,可使用len()函数,注意len()是函数不是方法,本例中len(a)表达式返回集合a的元素个数。
可变集合相似于列表,可变集合内容能够被修改,能够插入和删除元素。修改可变集合几个经常使用的方法。包括:
add(elem)。添加元素,若是元素已经存在,则不能添加,不会抛出错误。
remove(elem)。删除元素,若是元素不存在,则抛出错误。
discard(elem)。删除元素,若是元素不存在,不会抛出错误。
pop()。删除返回集合中任意一个元素,返回值是删除的元素。
在Python Shell中运行示例代码以下:
>>> student_set = {'张三', '李四', '王五'} >>> student_set.add('董六') >>> student_set {'张三', '董六', '李四', '王五'} >>> student_set.remove('李四') >>> student_set {'张三', '董六', '王五'} >>> student_set.remove('李四') ① Traceback (most recent call last): File "<pyshell#144>", line 1, in <module> student_set.remove('李四') KeyError: '李四' >>> student_set.discard('李四') ② >>> student_set {'张三', '董六', '王五'} >>> student_set.discard('王五') >>> student_set {'张三', '董六'} >>> student_set.pop() '张三' >>> student_set {'董六'} >>> student_set.clear() >>> student_set set()
上述代码第①行使用remove()方法删除元素时,因为要删除的'李四'已经不在集合中,因此会抛出错误。而一样是删除集合中不存在的元素discard()方法不会抛出错误,见代码第②行。
集合是无序的,没有索引,不能经过下标访问单个元素。但能够遍历集合,访问集合每个元素。
遍历集合通常是使用for循环,示例代码以下:
# coding=utf-8 # 代码文件:chapter9/ch9.3.3.py student_set = {'张三', '李四', '王五'} for item in student_set: print(item) print('-----------') for i, item in enumerate(student_set): ① print('{0} - {1}'.format(i, item))
输出结果以下:
张三 王五 李四 ----------- 0 - 张三 1 - 王五 2 - 李四
上述中使用for循环遍历集合,代码第①行的for循环中使用了enumerate()函数,该仍是在9.1.4节遍历元组时已经介绍过了,可是须要注意的是,此时变量i不是索引,只是遍历集合的次数。
不可变集合类型是frozenset,建立不可变集合使用frozenset([iterable])函数,不能使用大括号{}。在Python Shell中运行示例代码以下:
>>> student_set = frozenset({'张三', '李四', '王五'}) ① >>> student_set frozenset({'张三', '李四', '王五'}) >>> type(student_set) <class 'frozenset'> >>> student_set.add('董六') ② Traceback (most recent call last): File "<pyshell#168>", line 1, in <module> student_set.add('董六') AttributeError: 'frozenset' object has no attribute 'add' >>> a = (21, 32, 43, 45) >>> seta = frozenset(a) ③ >>> seta frozenset({32, 45, 43, 21})
上述代码第①行是建立不可变集合,frozenset()的参数{'张三', '李四',
'王五'}是另外一个集合对象,由于集合也是可迭代对象,能够做为frozenset()的参数。代码第③函数使用的了一个元组a做为frozenset()的参数。
因为建立的是不变集合,不能被修改,因此视图修改发生错误,见代码第②行,使用add()发生错误。
集合推导式与列表推断式相似,区别只是输出结构是集合。修改9.2.7节代码以下:
# coding=utf-8 # 代码文件:chapter9/ch9.3.5.py n_list = {x for x in range(100) if x % 2 == 0 if x % 5 == 0} print(n_list)
输出结构以下:
{0, 70, 40, 10, 80, 50, 20, 90, 60, 30}
因为集合是不能有重复元素的,集合推导式输出结果会过滤掉重复的元素,示例代码以下:
input_list = [2, 3, 2, 4, 5, 6, 6, 6] n_list = [x ** 2 for x in input_list] ① print(n_list) n_set = {x ** 2 for x in input_list} ② print(n_set)
输出结构以下:
[4, 9, 4, 16, 25, 36, 36, 36] {4, 36, 9, 16, 25}
上述代码第①行是列表推导式。代码第②行是集合推导式,从结果可见没有重复的元素。
字典(dict)是可迭代的、可变的数据结构,经过键来访问元素的数据结构。字典结构比较复杂,它是由两部分视图构成的:一个是键(key)视图;另外一个是值(value)视图。键视图不能包含重复元素的,而值集合能够,键和值是成对出现的。
图9-5所示是字典结构的“国家代号”。键是国家代号,值是国家。
提示
字典更适合经过键快速访问值,就像查英文字典同样,键就是要查的英文单词,而值是英文单词的翻译和解释等内容。有的时候,一个英文单词会对应多个翻译和解释,这也是与字典集合特性对应的。
字典类型是dict,建立字典可使用dict()函数,或者用大括号{}将“键:值”对包裹,“键:值”对之间用逗号分隔。
在Python Shell中运行示例代码以下:
>>> dict1 = {102: '张三', 105: '李四', 109: '王五'} ① >>> len(dict1) 3 >>> dict1 {102: '张三', 105: '李四', 109: '王五'} >>> type(dict1) <class 'dict'> >>> dict1 = {} >>> dict1 {} >>> dict({102: '张三', 105: '李四', 109: '王五'}) ② {102: '张三', 105: '李四', 109: '王五'} >>> dict(((102, '张三'), (105, '李四'), (109, '王五'))) ③ {102: '张三', 105: '李四', 109: '王五'} >>> dict([(102, '张三'), (105, '李四'), (109, '王五')]) ④ {102: '张三', 105: '李四', 109: '王五'} >>> t1 = (102, '张三') >>> t2 = (105, '李四') >>> t3 = (109, '王五') >>> t = (t1, t2, t3) >>> dict(t) ⑤ {102: '张三', 105: '李四', 109: '王五'} >>> list1 = [t1, t2, t3] >>> dict(list1) ⑥ {102: '张三', 105: '李四', 109: '王五'} >>> dict(zip([102, 105, 109], ['张三', '李四', '王五'])) ⑦ {102: '张三', 105: '李四', 109: '王五'}
上述代码第①行是使用大括号“键:值”对建立字典,这是最简单的建立字典方式了,那么建立一个空字典表达式是{}。得到字典长度(键值对个数)也是使用len()函数。
代码第②行、第③行、第④行、第⑤行和第⑥行都用dict()函数建立字典。代码第②行dict()函数参数是另一个字典{102:
'张三', 105: '李四', 109: '王五'},使用这种方式不如直接使用大括号“键:值”。
代码第③行和第⑤行参数是一个元组,这个元组中要包含三个只有两个元素的元组,建立过程参考如图9-6所示。代码第④行和第⑥行参数是一个列表,这个列表中包含三个只有两个元素的元组。
代码第⑦行是使用zip()函数,zip()函数将两个可迭代对象打包成元组,在建立字典时,可迭代对象元组,须要两个可迭代对象,第一个是键([102,
105, 109]),第二个是值(['张三', '李四',
'王五']),他们包含的元素个数相同,而且一一对应。
注意 使用dict()函数建立字典还可使用一种key=value形式参数,语法以下:
dict(key1=value1, key2=value2, key3=value3...)
key=value形式只能建立键是字符串类型的字典,使用时须要省略包裹字符串的引号(包括双引号或单引号)。在Python
Shell中运行示例代码以下:\>\>\> dict(102 = '张三', 105 = '李四', 109 = '王五') ①
SyntaxError: keyword can't be an expression
\>\>\> dict('102' = '张三', '105' = '李四', '109' = '王五') ②
SyntaxError: keyword can't be an expression
\>\>\> dict(S102 = '张三', S105 = '李四', S109 = '王五') ③
{'S102': '张三', 'S105': '李四', 'S109': '王五'}
代码第①行试图经过上述dict()函数建立键是整数类型的字典,结果会发生错误。代码第②行是试图使用字符串做为键建立字典,可是该dict()函数须要省略字符串键的引号,所以会发生错误。须要注意本例中键是由数字构成的字符串,他们很特殊若是省略包裹他们的引号,那么他们会表示为数字,使用该dict()函数是不容许的,因此此时的键不会识别字符串类型。代码第③行的键是在数字前面加S字母,这样不会识别为字符串类型。
字典能够被修改,但都是针对键和值同时操做,修改字典包括添加、替换和删除“键:值”对。
在Python Shell中运行示例代码以下:
>>> dict1 = {102: '张三', 105: '李四', 109: '王五'} >>> dict1[109] ① '王五' >>> dict1[110] = '董六' ② >>> dict1 {102: '张三', 105: '李四', 109: '王五', 110: '董六'} >>> dict1[109] = '张三' ③ >>> dict1 {102: '张三', 105: '李四', 109: '张三', 110: '董六'} >>> del dict1[109] ④ >>> dict1 {102: '张三', 105: '李四', 110: '董六'} >>> dict1.pop(105) '李四' >>> dict1 {102: '张三', 110: '董六'} >>> dict1.pop(105, '董六') ⑤ '董六' >>> dict1.popitem() ⑥ (110, '董六') >>> dict1 {102: '张三'}
访问字典中元素可经过下标实现,下标参数是键,返回对应的值,代码第①行是dict1[109]是取出字典dict1中键为109的值。字典下标访问元素也能够在赋值符号(=)左边,代码第②行是字典110键赋值,注意此时字典dict1中没有110键,那么这样的操做会添加110:
'董六'键值对。若是键存在那么会替换对应的值,代码第③行会将键109对应的值替换为'张三',虽然此时值视图中已经有'张三'了,但仍然能够添加,这说明值是能够重复的。
代码第④行是删除109键对应的值,注意del是语句不是函数。使用del语句删除键值对时,若是键不存在会抛出错误。
若是喜欢使用方法删除元素,可使用字典的pop(key[,
default])和popitem()方法。pop(key[,
default])方法删除键值对,若是键不存在则返回默认值(default),见代码第⑤行是105键不存在返回默认值'董六'。popitem()方法删除任意键值对,返回删除的键值对,构成的元组,上述代码第⑥行删除了一个键值对,返回一个元组对象(110,
'董六')。
字典还一些方法用来访问它的键或值,这些方法以下:
get(key[, default])。经过键返回值,若是键不存在返回默认值。
items()。返回字典的全部键值对。
keys()。返回字典键视图。
在Python Shell中运行示例代码以下:
>>> dict1 = {102: '张三', 105: '李四', 109: '王五'} >>> dict1.get(105) ① '李四' >>> dict1.get(101) ② >>> dict1.get(101, '董六') ③ '董六' >>> dict1.items() dict_items([(102, '张三'), (105, '李四'), (109, '王五')]) >>> dict1.keys() dict_keys([102, 105, 109]) >>> dict1.values() dict_values(['张三', '李四', '王五'])
上述代码第①行是经过get()方法返回105键对应的值,若是没有键对应的值,并且尚未为get()方法提供默认值,则不会有返回值,见代码第②行。代码第③行是提供了返回值。
在访问字典时,也可使用in和not in运算符,可是须要注意的是in和not
in运算符只测试键视图中进行。在Python Shell中运行示例代码以下:
>>> student_dict = {'102': '张三', '105': '李四', '109': '王五'} >>> 102 in dict1 True >>> '李四' in dict1 False
字典遍历也是字典的重要操做。与集合不一样,字典有两个视图,所以遍历过程能够只遍历值视图,也能够只遍历键视图,也能够同时遍历。这些遍历过程都是经过for循环实现的。
示例代码以下:
# coding=utf-8 # 代码文件:chapter9/ch9.4.4.py student_dict = {102: '张三', 105: '李四', 109: '王五'} print('---遍历键---') for student_id in student_dict.keys(): ① print('学号:' + str(student_id)) print('---遍历值---') for student_name in student_dict.values(): ② print('学生:' + student_name) print('---遍历键:值---') for student_id, student_name in student_dict.items(): ③ print('学号:{0} - 学生:{1}'.format(student_id, student_name))
输出结果以下:
---遍历键--- 学号:102 学号:105 学号:109 ---遍历值--- 学生:张三 学生:李四 学生:王五 ---遍历键:值--- 学号:102 - 学生:张三 学号:105 - 学生:李四 学号:109 - 学生:王五
上述代码第③行遍历字典的键值对,items()方法返回是键值对元组序列,student_id,
student_name是从元组拆包出来的两个变量。
由于字典包含了键和值两个不一样的结构,所以字典推导式结果能够很是灵活。字典推导示例代码以下:
# coding=utf-8 # 代码文件:chapter9/ch9.4.5.py input_dict = {'one': 1, 'two': 2, 'three': 3, 'four': 4} output_dict = {k: v for k, v in input_dict.items() if v % 2 == 0} ① print(output_dict) keys = [k for k, v in input_dict.items() if v % 2 == 0] ② print(keys)
输出结构以下:
{'two': 2, 'four': 4} ['two', 'four']
上述代码第①行是字典推导式,注意输入结构不能直接使用字典,由于字典不是序列,能够经过字典的item()方法返回字典中键值对序列。代码第②行是字典推导式,但只返回键结构。
本章介绍了Python中的几种数据结构。其中包括序列、元组、集合和字典,了解序列的特色,清楚序列包括哪些结构。而后详细介绍了元组、集合和字典。
http://www.zhijieketang.com/group/8
做者微博:@tony_关东升br/>邮箱:eorient@sina.com智捷课堂微信公共号:zhijieketangPython读者服务QQ群:628808216