python 的几种数据类型

列表 
列表是 Python  的主力数据类型。当提到 “ 列表 ” 时,您脑海中可
能会闪现“ 必须进一步声明大小的数组,只能包含同一类对象
“  等想法。千万别这么想。列表比那要酷得多。  
☞ Python  中的列表相似 Perl  5  中的数组。在 Perl  5  
中,存储数组的变量老是以字符 @ 开头;在 Python  
中,变量可随意命名,Python  仅在内部对数据类型
进行跟踪。 
☞ Python  中的列表更像 Java   中的数组(尽管能够
把列表当作生命中所须要的一切来使用)。一个更好
的比喻多是  ArrayList  类,该类能够容纳任何对
象,并可在添加新元素时进行动态拓展。 
建立列表 
列表建立很是轻松:使用中括号包裹一系列以逗号分割的值即
可。 
>>>  a_list = ['a',  'b', 'mpilgrim', 'z', 'example']  ① 
>>>  a_list 
['a',  'b', 'mpilgrim', 'z', 'example'] 
>>>  a_list[0]                                         ② 
'a'  
>>>  a_list[4]                                         ③ 
'example'  
>>>  a_list[ ‐1]                                       ④ 
'example'  
>>> a_list[ ‐3]                                       ⑤ 
'mpilgrim' 
1.   首先,建立一个包含 5 个元素的列表。要注意的是它们保持
了最初的顺序。这并非偶然的。列表是元素的有序集合。  
2.   列表可当作以零为基点的数组使用。非空列表的首个元素始
终是  a_list[0]  。  
3.   该 5 元素列表的最后一个元素是 a_list[4] ,由于列表(索
引)老是以零为基点的。  
4.   使用负索引值可从列表的尾部向前计数访问元素。任何非空
列表的最后一个元素老是 a_list[ ‐1] 。  
5.   若是负数令你混淆,可将其视为以下方式: a_list[ ‐n] == 
a_list[len(a_list)  ‐  n] 。所以在此列表中, a_list[ ‐3] == 
a_list[5 ‐  3] == a_list[2] 。 
列表切片 
a_list[0] 是列表的第一个元素。  
定义列表后,可从其中获取任何部分做为新列表。该技术称为
对列表进行 切片 。 
>>>  a_list 
['a',  'b', 'mpilgrim', 'z', 'example'] 
>>>  a_list[1:3]             ① 
['b',  'mpilgrim'] 
>>>  a_list[1: ‐1]           ② 
['b',  'mpilgrim', 'z'] 
>>>  a_list[0:3]             ③ 
['a',  'b', 'mpilgrim'] 
>>>  a_list[:3]             ④ 
['a',  'b', 'mpilgrim'] 
>>>  a_list[3:]             ⑤ 
['z',  'example'] 
>>> a_list[:]                ⑥ 
['a',  'b', 'mpilgrim', 'z', 'example'] 
1.   经过指定两个索引值,能够从列表中获取称做“ 切片” 的某个
部分。返回值是一个新列表,它包含列表(??切片)中全部元素,
按顺序从第一个切片索引开始(本例中为 a_list[1] ),截止但
不包含第二个切片索引(本例中的 a_list[3] )。  
2.   若是切片索引之一或二者均为负数,切片操做仍可进行。如
果有帮助的话,您能够这么思考:自左向右读取列表,第一个
切片索引指明了想要的第一个元素,第二个切片索引指明了第
一个不想要的元素。返回值是二者之间的任何值。 between.   
3.   列表是以零为起点的,所以 a_list[0:3] 返回列表的头三个
元素,从 a_list[0]  开始,截止到但不包括 a_list[3]  。  
4.   若是左切片索引为零,能够将其留空而将零隐去。所以 
a_list[:3] 与 a_list[0:3] 是彻底相同的,由于起点 0  被隐去
了。  
5.   一样,若是右切片索引为列表的长度,也能够将其留空。因
此 a_list[3:] 与 a_list[3:5] 是彻底相同的,由于该列表有五
个元素。此处有个好玩的对称现象。在这个五元素列表中, 
a_list[:3] 返回头三个元素,而 a_list[3:] 返回最后两个元
素。事实上,不管列表的长度是多少,  a_list[:n] 将返回头 n 个
元素,而 a_list[ n:] 返回其他部分。  
6.   若是两个切片索引都留空,那么将包括列表全部的元素。但
该返回值与最初的 a_list 变量并不同。它是一个新列表,只
不过刚好拥有彻底相同的元素而已。a_list[:]  是对列表进行复
制的一条捷径。 
向列表中新增项 
有四种方法可用于向列表中增长元素。 
>>>  a_list = ['a']  
>>>  a_list = a_list + [2.0,  3]    ① 
>>>  a_list                        ② 
['a',  2.0, 3] 
>>>  a_list.append(True)           ③ 
>>>  a_list 
['a',  2.0, 3, True]  
>>>  a_list.extend(['four', 'Ω'])   ④ 
>>>  a_list 
['a',  2.0, 3, True,  'four',  'Ω'] 
>>>  a_list.insert(0,  'Ω')          ⑤ 
>>> a_list 
['Ω', 'a', 2.0, 3, True,  'four',  'Ω'] 
1.   + 运算符链接列表以建立一个新列表。列表可包含任何数量
的元素;没有大小限制(除了可用内存的限制)。然而,若是
内存是个问题,那就必须知道在进行链接操做时,将在内存中
建立第二个列表。在该状况下,新列表将会当即被赋值给已有
变量 a_list 。所以,实际上该行代码包含两个步骤 —  链接而后
赋值 —  当处理大型列表时,该操做可能(暂时)消耗大量内
存。  
2.   列表可包含任何数据类型的元素,单个列表中的元素无须全
为同一类型。下面的列表中包含一个字符串、一个浮点数和一
个整数。  
3.   append() 方法向列表的尾部添加一个新的元素。(如今列表
中有 四种 不一样数据类型!)  
4.   列表是以类的形式实现的。“ 建立” 列表其实是将一个类实
例化。所以,列表有多种方法能够操做。extend() 方法只接受
一个列表做为参数,并将该参数的每一个元素都添加到原有的列
表中。  
5.   insert() 方法将单个元素插入到列表中。第一个参数是列表
中将被顶离原位的第一个元素的位置索引。列表中的元素并不
必定要是惟一的;好比说:现有两个各自独立的元素,其值均
为 'Ω':,第一个元素 a_list[0]  以及最后一个元素 a_list[6]  。 
☞a_list.insert(0, value ) 就像是 Perl  中的 
unshift()  函数。它将一个元素添加到列表的头
部,全部其它的元素都被顶理原先的位置以腾出空
间。 
让咱们进一步看看  append() 和 extend() 的区别。 
>>>  a_list = ['a',  'b', 'c'] 
>>>  a_list.extend(['d', 'e', 'f'])   ① 
>>>  a_list 
['a',  'b', 'c', 'd', 'e', 'f'] 
>>>  len(a_list)                     ② 

>>>  a_list[ ‐1] 
'f'  
>>>  a_list.append(['g', 'h', 'i'])   ③ 
>>>  a_list 
['a',  'b', 'c', 'd', 'e', 'f', ['g',  'h', 'i']]  
>>>  len(a_list)                     ④ 

>>> a_list[ ‐1] 
['g',  'h', 'i'] 
1.   extend() 方法只接受一个参数,而该参数老是一个列表,并
将列表 a_list 中全部的元素都添加到该列表中。  
2.   若是开始有个 3 元素列表,而后将它与另外一个 3 元素列表进
行 extend  操做,结果是将得到一个 6 元素列表。  
3.   另外一方面, append() 方法只接受一个参数,但能够是任何数
据类型。在此,对一个 3 元素列表调用 append() 方法。  
4.   若是开始的时候有个 6 元素列表,而后将一个列表 append
[添加]上去,结果就会……获得一个 7 元素列表。为何是 7 
个?由于最后一个元素(刚刚 append[添加] 的元素) 自己
是个列表 。列表可包含任何类型的数据,包括其它列表。这可
能是你所须要的结果,也许不是。但若是这就是你想要的,那
这就是你所获得的。 
在列表中检索值 
>>>  a_list = ['a',  'b', 'new', 'mpilgrim', 'new'] 
>>>  a_list.count('new')        ① 

>>>  'new'  in a_list           ② 
True 
>>>  'c'  in a_list 
False  
>>>  a_list.index('mpilgrim')  ③ 

>>>  a_list.index('new')        ④ 

>>>  a_list.index('c')          ⑤ 
Traceback  (innermost last): 
  File  "<interactive input>", line 1, in ?ValueError:  
list.index(x):  x not  in list 
1.   如你所指望,  count()  方法返回了列表中某个特定值出现的
次数。  
2.   若是你想知道的是某个值是否出如今列表中, in 运算符将会
比使用 count()  方法要略快一些。in 运算符老是返回 True 或 
False ;它不会告诉你该值出如今什么位置。  
3.   若是想知道某个值在列表中的精确位置,可调用 index()  方
法。尽管能够经过第二个参数(以 0  为基点的)索引值来指定
起点,经过第三个参数(以 0  基点的)索引来指定搜索终点,
但缺省状况下它将搜索整个列表,  
4.   index()  方法将查找某值在列表中的第一次出现。在该状况
下,'new'  在列表中出现了两次,分别为 a_list[2]  和 
a_list[4] ,但 index()  方法将只返回第一次出现的位置索引
值。  
5.   可能 出乎 您的预期,若是在列表中没有找到该值,index()  
方法将会引起一个例外。 
等等,什么?是这样的:若是没有在列表中找到该值, index()  
方法将会引起一个例外。这是 Python  语言最显著不一样之处,其
它多数语言将会返回一些无效的索引值(像是 ‐1)。固然,一
开始这一点看起来比较讨厌,但我想您会逐渐欣赏它。这意味
着您的程序将会在问题的源头处崩溃,而不是以后奇怪地、默
默地崩溃。请记住, ‐1 是合法的列表索引值。若是 index()  方
法返回 ‐1,可能会致使调整过程变得不那么有趣!  
从列表中删除元素 
列表永远不会有缝隙。  
列表能够自动拓展或者收缩。您已经看到了拓展部分。也有几
种方法可从列表中删除元素。 
>>>  a_list = ['a',  'b', 'new', 'mpilgrim', 'new'] 
>>>  a_list[1]  
'b'  
>>>  del  a_list[1]           ① 
>>>  a_list 
['a',  'new', 'mpilgrim', 'new'] 
>>> a_list[1]              ② 
'new'  
1.   可以使用  del  语句从列表中删除某个特定元素。  
2.   删除索引  1 以后再访问索引 1 将 不会 致使错误。被删除元素
以后的全部元素将移动它们的位置以“ 填补” 被删除元素所产生
的“ 缝隙” 。 
不知道位置索引?这不成问题,您能够经过值而不是索引删除
元素。 
>>>  a_list.remove('new')  ① 
>>>  a_list 
['a',  'mpilgrim', 'new'] 
>>>  a_list.remove('new')  ② 
>>>  a_list 
['a',  'mpilgrim'] 
>>>  a_list.remove('new') 
Traceback  (most  recent call last): 
  File  "<stdin>", line 1, in <module> 
ValueError:  list.remove(x): x not  in list 
1.   还能够经过  remove() 方法从列表中删除某个元素。remove() 
方法接受一个 value 参数,并删除列表中该值的第一次出现。同
样,被删除元素以后的全部元素将会将索引位置下移,以“ 填补
缝隙” 。列表永远不会有“ 缝隙” 。  
2.   您能够尽情地调用 remove() 方法,但若是试图删除列表中不
存在的元素,它将引起一个例外。 
R EMOVING I TEMS FROM  A  LIST :  BONUS 
R OUND 
另外一有趣的列表方法是 pop()  。pop()  方法是从列表删除元素的
另外一方法,但有点变化。 
>>>  a_list = ['a',  'b', 'new', 'mpilgrim'] 
>>>  a_list.pop()     ① 
'mpilgrim' 
>>>  a_list 
['a',  'b', 'new'] 
>>>  a_list.pop(1)  ② 
'b'  
>>>  a_list 
['a',  'new'] 
>>>  a_list.pop()  
'new'  
>>>  a_list.pop()  
'a'  
>>>  a_list.pop()     ③ 
Traceback  (most  recent call last): 
  File  "<stdin>", line 1, in <module> 
IndexError:  pop  from empty  list 
1.   若是不带参数调用,  pop()  列表方法将删除列表中最后的元
素,并返回所删除的值。  
2.   能够从列表中 pop [弹出]任何元素。只需传给 pop()  方法
一个位置索引值。它将删除该元素,将其后全部元素移位以“ 填
补缝隙”, 而后返回它删除的值。  
3.   对空列表调用 pop()  将会引起一个例外。 
☞不带参数调用的 pop()  列表方法就像 Perl  中的 
pop()  函数。它从列表中删除最后一个元素并返回
所删除元素的值。Perl  还有另外一个函数  shift() ,
可用于删除第一个元素并返回其值;在 Python  
中,该函数至关于 a_list.pop(0)  。 
布尔上下文环境中的列表 
空列表为假;其它全部列表为真。  
能够在 if 这样的 布尔类型上下文环境中 使用列表。 
>>>  def  is_it_true(anything): 
...    if anything:  
...      print("yes, it's true") 
...    else:  
...      print("no, it's false")  
...  
>>>  is_it_true([])              ① 
no,  it's false  
>>>  is_it_true(['a'])          ② 
yes, it's true 
>>> is_it_true([False])        ③ 
yes, it's true 
1.   在布尔类型上下文环境中,空列表为假值。  
2.   任何至少包含一个上元素的列表为真值。  
3.   任何至少包含一个上元素的列表为真值。元素的值无关紧
要。 
⁂  
元组 
元素 是不可变的列表。一旦建立以后,用任何方法都不能够修
改元素。 
>>>  a_tuple  = ("a",  "b", "mpilgrim", "z", "example")  ① 
>>>  a_tuple  
('a',  'b', 'mpilgrim', 'z', 'example') 
>>>  a_tuple[0]                                        ② 
'a'  
>>>  a_tuple[‐1]                                       ③ 
'example'  
>>> a_tuple[1:3]                                        ④ 
('b',  'mpilgrim') 
1.   元组的定义方式和列表相同,除了整个元素的集合都用圆括
号,而不是方括号闭合。  
2.   和列表同样,元组的元素都有肯定的顺序。元组的索引也是
以零为基点的,和列表同样,所以非空元组的第一个元素老是 
a_tuple[0] 。  
3.   负的索引从元组的尾部开始计数,这和列表也是同样的。  
4.   和列表同样,元组也能够进行切片操做。对列表切片能够得
到新的列表;对元组切片能够获得新的元组。 
元组和列表的主要区别是元组不能进行修改。用技术术语来
说,元组是 不可变动 的。从实践的角度来讲,没有可用于修改
元组的方法。列表有像 append()、 extend()、 insert()、
remove() 和 pop()  这样的方法。这些方法,元组都没有。能够
对元组进行切片操做(由于该方法建立一个新的元组),能够
检查元组是否包含了特定的值(由于该操做不修改元组),还
能够……就那么多了。 
# continued  from the  previous example  
>>>  a_tuple  
('a',  'b', 'mpilgrim', 'z', 'example') 
>>>  a_tuple.append("new")               ① 
Traceback  (innermost last): 
  File  "<interactive  input>",  line  1,  in  ?AttributeError:  
'tuple'  object has  no attribute  'append' 
>>>  a_tuple.remove("z")                 ② 
Traceback  (innermost last): 
  File  "<interactive  input>",  line  1,  in  ?AttributeError:  
'tuple'  object has  no attribute  'remove' 
>>>  a_tuple.index("example")             ③ 

>>> "z"  in a_tuple                       ④ 
True 
1.   没法向元组添加元素。元组没有  append() 或 extend() 方
法。  
2.   不能从元组中删除元素。元组没有 remove() 或 pop()  方法。  
3.   能够 在元组中查找元素,因为该操做不改变元组。  
4.   还可使用 in 运算符检查某元素是否存在于元组中。 
那么元组有什么好处呢? 
•   元组的速度比列表更快。若是定义了一系列常量值,而所需
作的仅是对它进行遍历,那么请使用元组替代列表。  
•   对不须要改变的数据进行“ 写保护” 将使得代码更加安全。使
用元组替代列表就像是有一条隐含的 assert 语句显示该数据是
常量,特别的想法(及特别的功能)必须重写。(??)  
•   一些元组可用做字典键(特别是包含字符串、数值和其它元
组这样的不可变数据的元组)。列表永远不能当作字典键使
用,由于列表不是不可变的。 
☞元组可转换成列表,反之亦然。内建
的 tuple()  函数接受一个列表参数,并返回
一个包含一样元素的元组,而 list() 函数
接受一个元组参数并返回一个列表。从效
果上看, tuple()  冻结列表,而 list() 融
化元组。 
布尔上下文环境中的元组 
能够在 if 这样的 布尔类型上下文环境中 使用元组。 
>>>  def  is_it_true(anything): 
...    if anything:  
...      print("yes, it's true") 
...    else:  
...      print("no, it's false")  
...  
>>>  is_it_true(())              ① 
no,  it's false  
>>>  is_it_true(('a',  'b'))       ② 
yes, it's true 
>>>  is_it_true((False,))        ③ 
yes, it's true 
>>>  type((False))               ④ 
<class 'bool'>  
>>> type((False,))  
<class 'tuple'> 
1.   在布尔类型上下文环境中,空元组为假值。  
2.   任何至少包含一个上元素的元组为真值。  
3.   任何至少包含一个上元素的元组为真值。元素的值无关紧
要。不过此处的逗号起什么做用呢?  
4.   为建立单元素元组,须要在值以后加上一个逗号。没有逗
号,Python  会假定这只是一对额外的圆括号,虽然没有害处,
但并不建立元组。 
同时赋多个值 
如下是一种很酷的编程捷径:在 Python  中,可以使用元组来一次
赋多值。 
>>>  v = ('a',  2, True)  
>>>  (x,  y, z) = v        ① 
>>>  x 
'a'  
>>>  y 

>>> z 
True 
1.   v 是一个三元素的元组,而 (x,  y, z) 是包含三个变量的元
组。将其中一个赋值给另外一个将会把 v 中的每一个值按顺序赋值
给每个变量。 
该特性有多种用途。假设须要将某个名称指定某个特定范围的
值。可使用内建的 range()  函数进行多变量赋值以快速地进
行连续变量赋值。 
>>>  (MONDAY, TUESDAY, WEDNESDAY, THURSDAY,  FRIDAY,  
SATURDAY,  SUNDAY)  = range(7)  ① 
>>>  MONDAY                                                                
② 

>>>  TUESDAY  

>>> SUNDAY 

1.   内建的  range()  函数构造了一个整数序列。(从技术上来
说, range()  函数返回的既不是列表也不是元组,而是一个 迭
代器,但稍后您将学到它们的区别。) MONDAY、 TUESDAY 、 
WEDNESDAY 、 THURSDAY、 FRIDAY、 SATURDAY 和 SUNDAY 是您所定
义的变量。(本例来自于 calendar 模块,该短小而有趣的模块
打印日历,有点像 UNIX 程序 cal  。该 calendar 模块为星期数
定义了整数常量。  
2.   如今,每一个变量都有其值了: MONDAY 为 0 , TUESDAY  为 1,
如此类推。 
还可使用多变量赋值建立返回多值的函数,只需返回一个包
含全部值的元组。调用者可将返回值视为一个简单的元组,或
将其赋值给不一样的变量。许多标准 Python  类库这么干,包括在
下一章将学到的 os 模块。  
⁂  
集合 
集合set 是装有独特值的无序“ 袋子” 。一个简单的集合能够包含
任何数据类型的值。若是有两个集合,则能够执行像联合、交
集以及集合求差等标准集合运算。  
建立集合 
重中之重。建立集合很是简单。 
>>>  a_set  = {1}       ① 
>>>  a_set  
{1}  
>>>  type(a_set)      ② 
<class 'set'> 
>>>  a_set  = {1,  2}  ③ 
>>> a_set  
{1, 2} 
1.   要建立只包含一个值的集合,仅需将该值放置于花括号之
间。({})。  
2.   实际上,集合以 类 的形式实现,但目前还无须考虑这一点。  
3.   要建立多值集合,请将值用逗号分开,并用花括号将全部值
包裹起来。 
还能够 列表 为基础建立集合。 
>>>  a_list = ['a',  'b', 'mpilgrim', True,  False, 42]  
>>>  a_set  = set(a_list)                            ① 
>>>  a_set                                          ② 
{'a',  False, 'b', True,  'mpilgrim', 42}  
>>> a_list                                        ③ 
['a',  'b', 'mpilgrim', True,  False, 42]  
1.   要从列表建立集合,可以使用  set()  函数。(懂得如何实现集
合的学究可能指出这实际上并非调用某个函数,而是对某个
类进行实例化。我保证在本书稍后的地方将会学到其中的区
别。目前而言,仅需知道 set()  行为与函数相似,以及它返回
一个集合。)  
2.   正如我以前提到的,简单的集合能够包括任何数据类型的
值。并且,如我以前所提到的,集合是 无序的。该集合并不记
得用于建立它的列表中元素的最初顺序。若是向集合中添加元
素,它也不会记得添加的顺序。  
3.   初始的列表并不会发生变化。 
尚未任何值?没有问题。能够建立一个空的集合。 
>>>  a_set  = set()     ① 
>>>  a_set              ② 
set()  
>>>  type(a_set)      ③ 
<class 'set'> 
>>>  len(a_set)        ④ 

>>>  not_sure = {}    ⑤ 
>>> type(not_sure)  
<class 'dict'>  
1.   要建立空集合,可不带参数调用  set()  。  
2.   打印出来的空集合表现形式看起来有点儿怪。也许,您指望
看到一个  {} 吧 ?该符号表示一个空的字典,而不是一个空的集
合。本章稍后您将学到关于字典的内容。  
3.   尽管打印出的形式奇怪,这 确实是 一个集合……  
4.   …… 同时该集合没有任何成员。  
5.   因为从 Python  2 沿袭而来历史的古怪规定,不能使用两个花
括号来建立空集合。该操做实际建立一个空字典,而不是一个
空集合。 
修改集合 
有两种方法可向现有集合中添加值: add()  方法和 update() 方
法。 
>>>  a_set  = {1,  2} 
>>>  a_set.add(4)   ① 
>>>  a_set  
{1,  2, 4} 
>>>  len(a_set)    ② 

>>>  a_set.add(1)   ③ 
>>>  a_set  
{1,  2, 4} 
>>> len(a_set)    ④ 

1.   add()  方法接受单个能够是任何数据类型的参数,并将该值
添加到集合之中。  
2.   该集合如今有三个成员了。  
3.   集合是装 惟一值 的袋子。若是试图添加一个集合中已有的
值,将不会发生任何事情。将不会引起一个错误;只是一条空
操做。  
4.   该集合 仍然 只有三个成员。 
>>>  a_set  = {1,  2, 3} 
>>>  a_set  
{1,  2, 3} 
>>>  a_set.update({2,  4, 6})                         ① 
>>>  a_set                                          ② 
{1,  2, 3, 4, 6} 
>>>  a_set.update({3,  6, 9},  {1,  2, 3, 5, 8, 13})  ③ 
>>>  a_set  
{1,  2, 3, 4, 5, 6, 8, 9, 13}  
>>>  a_set.update([10, 20,  30])                    ④ 
>>> a_set  
{1, 2, 3, 4, 5, 6, 8, 9, 10,  13,  20,  30}  
1.   update() 方法仅接受一个集合做为参数,并将其全部成员添
加到初始列表中。其行为方式就像是对参数集合中的每一个成员
调用 add()  方法。  
2.   因为集合不能包含重复的值,所以重复的值将会被忽略。  
3.   实际上,能够带任何数量的参数调用 update() 方法。若是调
用时传递了两个集合, update() 将会被每一个集合中的每一个成员
添加到初始的集合当中(丢弃重复值)。  
4.   update() 方法还可接受一些其它数据类型的对象做为参数,
包括列表。若是调用时传入列表,update() 将会把列表中全部
的元素添加到初始集合中。 
从集合中删除元素 
有三种方法能够用来从集合中删除某个值。前两种,discard()  
和 remove() 有细微的差别。 
>>>  a_set  = {1,  3, 6, 10,  15,  21,  28,  36,  45}  
>>>  a_set  
{1,  3, 36,  6, 10,  45,  15,  21,  28}  
>>>  a_set.discard(10)                        ① 
>>>  a_set  
{1,  3, 36,  6, 45,  15,  21,  28}  
>>>  a_set.discard(10)                        ② 
>>>  a_set  
{1,  3, 36,  6, 45,  15,  21,  28}  
>>>  a_set.remove(21)                           ③ 
>>>  a_set  
{1,  3, 36,  6, 45,  15,  28}  
>>>  a_set.remove(21)                           ④ 
Traceback  (most  recent call last): 
  File  "<stdin>", line 1, in <module> 
KeyError:  21 
1.   discard()  接受一个单值做为参数,并从集合中删除该值。  
2.   若是针对一个集合中不存在的值调用 discard()  方法,它不
进行任何操做。不产生错误;只是一条空指令。  
3.   remove() 方法也接受一个单值做为参数,也从集合中将其删
除。  
4.   区别在这里:若是该值不在集合中,remove() 方法引起一个 
KeyError 例外。 
就像列表,集合也有个 pop()  方法。 
>>>  a_set  = {1,  3, 6, 10,  15,  21,  28,  36,  45}  
>>>  a_set.pop()                                 ① 

>>>  a_set.pop() 

>>>  a_set.pop() 
36 
>>>  a_set  
{6,  10,  45,  15,  21,  28}  
>>>  a_set.clear()                              ② 
>>>  a_set  
set()  
>>>  a_set.pop()                                 ③ 
Traceback  (most  recent call last): 
  File  "<stdin>", line 1, in <module> 
KeyError:  'pop from an empty  set' 
1.   pop()  方法从集合中删除某个值,并返回该值。然而,因为
集合是无序的,并无“ 最后一个” 值的概念,所以没法控制删
除的是哪个值。它基本上是随机的。  
2.   clear()  方法删除集合中 全部 的值,留下一个空集合。它等
价于 a_set  = set() ,该语句建立一个新的空集合,并用之覆盖 
a_set  变量的以前的值。  
3.   试图从空集合中弹出某值将会引起 KeyError 例外。 
常见集合操做 
Python  的 集合 类型支持几种常见的运算。 
>>>  a_set  = {2,  4, 5, 9, 12,  21,  30,  51,  76,  127, 195} 
>>>  30 in a_set                                                      
① 
True 
>>>  31 in a_set  
False  
>>>  b_set  = {1,  2, 3, 5, 6, 8, 9, 12,  15,  17,  18,  21}  
>>>  a_set.union(b_set)                                               
② 
{1,  2, 195, 4, 5, 6, 8, 12,  76,  15,  17,  18,  3, 21,  30,  
51,  9, 127} 
>>>  a_set.intersection(b_set)                                        
③ 
{9,  2, 12,  5, 21}  
>>>  a_set.difference(b_set)                                          
④ 
{195,  4, 76,  51,  30,  127} 
>>> a_set.symmetric_difference(b_set)                               
⑤ 
{1, 3, 4, 6, 8, 76,  15,  17,  18,  195, 127, 30,  51}  
1.   要检测某值是不是集合的成员,可以使用  in 运算符。其工做原
理和列表的同样。  
2.   union()  方法返回一个新集合,其中装着 在两个 集合中出现
的元素。  
3.   intersection()  方法返回一个新集合,其中装着 同时 在两个
集合中出现的全部元素。  
4.   difference()  方法返回的新集合中,装着全部在 a_set  出现
但未在 b_set  中的元素。  
5.   symmetric_difference() 方法返回一个新集合,其中装着所
有 只在其中一个 集合中出现的元素。 
这三种方法是对称的。 
# continued  from the  previous example  
>>>  b_set.symmetric_difference(a_set)                                     
① 
{3,  1, 195, 4, 6, 8, 76,  15,  17,  18,  51,  30,  127} 
>>>  b_set.symmetric_difference(a_set) == 
a_set.symmetric_difference(b_set)  ② 
True 
>>>  b_set.union(a_set)  == a_set.union(b_set)                               
③ 
True 
>>>  b_set.intersection(a_set)  == 
a_set.intersection(b_set)                    ④ 
True 
>>> b_set.difference(a_set)  == a_set.difference(b_set)                     
⑤ 
False  
1.   a_set  与 b_set  的对称差分 看起来 和b_set  与 a_set  的对称
差分不一样,但请记住:集合是无序的。任何两个包含全部一样
值(无一遗漏)的集合可认为是相等的。  
2.   而这正是这里发生的事情。不要被 Python  Shell 对这些集合
的输出形式所愚弄了。它们包含相同的值,所以是相等的。  
3.   对两个集合的 Union[并集]操做也是对称的。  
4.   对两个集合的 Intersection [交集]操做也是对称的。  
5.   对两个集合的 Difference[求差]操做不是对称的。这是有意
义的;它相似于从一个数中减去另外一个数。操做数的顺序会导
致结果不一样。 
最后,有几个您可能会问到的问题。 
>>>  a_set  = {1,  2, 3} 
>>>  b_set  = {1,  2, 3, 4} 
>>>  a_set.issubset(b_set)    ① 
True 
>>>  b_set.issuperset(a_set)   ② 
True 
>>>  a_set.add(5)              ③ 
>>>  a_set.issubset(b_set) 
False  
>>> b_set.issuperset(a_set)  
False  
1.   a_set  是 b_set  的 子集 —  全部 a_set  的成员均为 b_set  的成
员。  
2.   一样的问题反过来讲, b_set  是 a_set  的 超集,由于 a_set  
的全部成员均为 b_set  的成员。  
3.   一旦向 a_set  添加一个未在 b_set  中出现的值,两项测试均
返回 False  。 
布尔上下文环境中的集合 
可在 if 这样的 布尔类型上下文环境中 使用集合。 
>>>  def  is_it_true(anything): 
...    if anything:  
...      print("yes, it's true") 
...    else:  
...      print("no, it's false")  
...  
>>>  is_it_true(set())          ① 
no,  it's false  
>>>  is_it_true({'a'})          ② 
yes, it's true 
>>> is_it_true({False})        ③ 
yes, it's true 
1.   在布尔类型上下文环境中,空集合为假值。  
2.   任何至少包含一个上元素的集合为真值。  
3.   任何至少包含一个上元素的集合为真值。元素的值无关紧
要。 
⁂  
字典 
字典 是键值对的无序集合。向字典添加一个键的同时,必须为
该键增添一个值。(以后可随时修改该值。) Python  的字典为
经过键获取值进行了优化,而不是反过来。  
☞Python  中的字典与 Perl  5  中的 hash  [ 散列] 相似。
在 Perl  5  中,散列存储的变量老是以一个 % 符开
头。在 Python  中,变量能够随意命名,而 Python  
内部跟踪其数据类型。 
建立字典 
建立字典很是简单。其语法与 集合 的相似,但应当指定键值对
而不是值。有了字典后,能够经过键来查找值。 
>>>  a_dict = {'server': 'db.diveintopython3.org',  
'database': 'mysql'}  ① 
>>>  a_dict 
{'server':  'db.diveintopython3.org',   'database':  'mysql'} 
>>>  a_dict['server']                                                     
② 
'db.diveintopython3.org' 
>>>  a_dict['database']                                                   
③ 
'mysql'  
>>>  a_dict['db.diveintopython3.org']                                     
④ 
Traceback  (most  recent call last): 
  File  "<stdin>", line 1, in <module> 
KeyError:  'db.diveintopython3.org' 
1.   首先,经过将两个字典项指定给  a_dict 变量建立了一个新字
典。每一个字典项都是一组键值对,整个字典项集合都被大括号
包裹在内。  
2.   'server' 为键,经过 a_dict['server']  引用的关联值为 
'db.diveintopython3.org' 。  
3.   'database' 为键,经过 a_dict['database']  引用的关联值为 
'mysql'  。  
4.   能够经过键获取值,但不能经过值获取键。所以 
a_dict['server']  为 'db.diveintopython3.org',而 
a_dict['db.diveintopython3.org']  会引起例外,由于 
'db.diveintopython3.org' 并非键。 
修改字典 
字典没有预约义的大小限制。能够随时向字典中添加新的键值
对,或者修改现有键所关联的值。继续前面的例子: 
>>>  a_dict 
{'server':  'db.diveintopython3.org',   'database':  'mysql'} 
>>>  a_dict['database']  = 'blog'  ① 
>>>  a_dict 
{'server': 'db.diveintopython3.org',  'database': 'blog'}  
>>>  a_dict['user']  = 'mark'      ② 
>>>  a_dict                        ③ 
{'server': 'db.diveintopython3.org',  'user':  'mark',  
'database': 'blog'}  
>>>  a_dict['user']  = 'dora'      ④ 
>>>  a_dict 
{'server': 'db.diveintopython3.org',  'user':  'dora',  
'database': 'blog'}  
>>>  a_dict['User']  = 'mark'      ⑤ 
>>> a_dict 
{'User': 'mark',  'server':  'db.diveintopython3.org',  
'user':  'dora',  'database': 'blog'}  
1.   在字典中不容许有重复的键。对现有的键赋值将会覆盖旧
值。  
2.   可随时添加新的键值对。该语法与修改现有值相同。  
3.   新字典项(键为 'user',值为 'mark')出如今中间。事实
上,在第一个例子中字典项按顺序出现是个巧合;如今它们不
按顺序出现一样也是个巧合。  
4.   对既有字典键进行赋值只会用新值替代旧值。  
5.   该操做会将  user 键的值改回 "mark"  吗?不会!仔细看看该
键——有个大写的  U 出如今 "User" 中。字典键是区分大小写
的,所以该语句建立了一组新的键值对,而不是覆盖既有的字
典项。对你来讲它们多是同样的,但对于 Python  而言它们是
彻底不一样的。 
混合值字典 
字典并不是只能用于字符串。字典的值能够是任何数据类型,包
括整数、布尔值、任何对象,甚至是其它的字典。并且就算在
同一字典中,全部的值也无须是同一类型,您可根据须要混合
匹配。字典的键要严格得多,能够是字符串、整数和其它一些
类型。在同一字典中也可混合、匹配使用不一样数据类型的键。  
实际上,您已经在 your  first  Python  program  见过一个将非字符
串用做键的字典了。 
SUFFIXES = {1000: ['KB', 'MB',  'GB',  'TB',  'PB',  'EB',  
'ZB',  'YB'], 
             1024:  ['KiB',  'MiB', 'GiB', 'TiB', 'PiB', 
'EiB', 'ZiB', 'YiB']}  
让咱们在交互式 shell  中剖析一下: 
>>>  SUFFIXES = {1000: ['KB', 'MB',  'GB',  'TB',  'PB',  
'EB',  'ZB',  'YB'], 
...                1024:   ['KiB',   'MiB',  'GiB',  'TiB',  'PiB', 
'EiB', 'ZiB', 'YiB']}  
>>>  len(SUFFIXES)      ① 

>>>  1000 in SUFFIXES    ② 
True 
>>>  SUFFIXES[1000]       ③ 
['KB', 'MB',  'GB',  'TB',  'PB',  'EB',  'ZB',  'YB']  
>>>  SUFFIXES[1024]       ④ 
['KiB',  'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] 
>>> SUFFIXES[1000][3]  ⑤ 
'TB' 
1.   相似 列表 和 集合 ,len()  函数将返回字典中键的数量。  
2.   并且像列表和集合同样,可以使用  in 运算符以测试某个特定的
键是否在字典中。  
3.   1000 是 字典 SUFFIXES 的一个键;其值为一个 8  元素列表
(确切地说,是 8  个字符串)。  
4.   一样, 1024 是字典 SUFFIXES 的键;其值也是一个 8  元素列
表。  
5.   因为 SUFFIXES[1000]  是列表,能够经过它们的 0  基点索引来
获取列表中的单个元素。 
布尔上下文环境中的字典 
空字典为假值;全部其它字典为真值。  
能够在 if 这样的 布尔类型上下文环境中 使用字典。 
>>>  def  is_it_true(anything): 
...    if anything:  
...      print("yes, it's true") 
...    else:  
...      print("no, it's false")  
...  
>>>  is_it_true({})              ① 
no,  it's false  
>>> is_it_true({'a':  1})         ② 
yes, it's true 
1.   在布尔类型上下文环境中,空字典为假值。  
2.   至少包含一个键值对的字典为真值。 
⁂  
NONE  
None 是 Python  的一个特殊常量。它是一个 空 值。None 与 
False  不一样。None 不是 0  。None 不是空字符串。将 None 与任何
非  None 的东西进行比较将老是返回 False  。  
None 是惟一的空值。它有着本身的数据类型(NoneType)。可
将  None 赋值给任何变量,但不能建立其它 NoneType 对象。所
有值为  None 变量是相等的。 
>>>  type(None) 
<class 'NoneType'> 
>>>  None == False  
False  
>>>  None == 0 
False  
>>>  None == '' 
False  
>>>  None == None 
True 
>>>  x = None 
>>>  x == None 
True 
>>>  y = None 
>>>  x == y 
True 
布尔上下文环境中的  NONE  
在 布尔类型上下文环境中, None 为假值,而 not  None 为真
值。 
>>>  def  is_it_true(anything): 
...    if anything:  
...      print("yes, it's true") 
...    else:  
...      print("no, it's false")  
...  
>>>  is_it_true(None)  
no,  it's false  
>>>  is_it_true(not  None)  
yes, it's true 
python

相关文章
相关标签/搜索