第二章 ==========
对象的类型决定了可以对它进行的操作。对象的类型还决定了它装着的数据是允许被修改的变量(可变的),还是不可被修改的常量(不可变的)。
Python是强类型的,你永远无法修改一个已有对象的类型,即使它包含的值是可变的。
变量,就是在程序中为了方便地引用内存中的值而为它取的名字,在Python中,用 = 来给一个变量赋值。python中的变量有一个非常重要的性质:它仅仅是一个名字。赋值操作并不会实际复制值,它只是为数据对象取一个相关的名字,名字是对对象的引用而不是对象本身。
在Python中,如果想知道一个对象的类型,可以使用语句:type( thing )。
Python中以下划线开头的变量名有特殊的含义。
使用 int() 函数将其他数据类型转换为整形,它会保留传入数据的整数部分并舍去小数部分。int() 可以接受浮点数或者由数字组成的字符串,但无法接受包含小数点或指数的字符串。
布尔型,只有两个可选值:True 和 False 。当转换为整数时,分别为 1 和 0 。
浮点型,转换为整数时,所有的小数点后面的部分会被舍去。
可以将仅包含数字和正负号的字符串转换为整数。
如果混合使用多种不同的数字类型进行计算,Python 会自动地进行类型转换。与整数或浮点数混合使用市,布尔型的False会被当作 0 或者 0.0 ,True 会被当作 1 或者 1.0 。
Python3里,int 类型变为可以存储任意大小的整数,甚至超过 64 位。
在计算中的数字或结果需要的存储空间超过了计算机所提供的空间,就会造成整数溢出。
float() 函数可以将其他数字类型转换为浮点型。布尔型在计算中等价于 1.0 和 0.0 。也可以将包含有效浮点数(数字,正负号,小数点,指数及指数的前缀e)的字符串转换为真正的浮点型数字。
对 Unicode 的支持使得 Python 3 可以包含世界上任何书面语言以及许多特殊符号。
字符串型,是一种序列类型,它的本质是字符序列。Python 字符串是不可变的,无法对原字符串进行修改,但可以将字符串的一部分复制到新字符串,来打到相同的修改效果。
将一系列字符包裹在一对单引号或一对双引号中即可创建字符串。单引号和双引号包裹的字符,没有任何区别。可以在双引号包裹的字符串中使用单引号,或者在单引号包裹的字符串中使用双引号。
还可以使用连续三个单引号''',或者连续三个双引号""",创建字符串。三元引号多用于创建多行字符串。
print() 会把包裹字符串的引号去掉,仅输出其实际内容,易于阅读,还会自动地在各个输出部分之间添加空格,并在所有输出的最后添加换行符。
解释器可以打印字符串以及像 \n 的转义符。
Python 允许空串的存在,它不包含任何字符且完全合法。
str() 可以将其他Python 数据类型转换为字符串。当你调用print() 函数或者进行 字符串差值 时,Python 内部会自动使用 str() 将非字符串对象转换为字符串。
Python 允许你对某些字符进行转义操作,以此来实现一些难以单纯用字符描述的效果。
在Python 中,可以使用 + 将多个字符串或字符串变量拼接起来。也可以直接将一个字面字符串(非字符串变量)放到另一个的后面直接实现拼接。
在字符串名后面添加[ ],并在括号里指定偏移量可以提取该位置的单个字符。第一个字符的偏移量为 0 ,最后一个字符的偏移量也可以用 -1 表示,这样就不用从头到尾数。偏移量从右到左紧接着为 -2, -3, 以此类推。如果指定的偏移量超过了字符串的长度,会收到一个异常提醒。位置索引在其他序列类型(列表和元组)中的使用也是如此。
由于字符串是不可变的,因此无法直接插入字符或改变指定位置的字符。
分片操作:可以从一个字符串中抽取子字符串(字符串的一部分)。使用一对方括号,起始偏移量start,终止偏移量 end 以及可选的步长 step 来定义一个分片。其中一个可以省略。分片得到的子串,包含从 start 开始到 end 之前的全部字符。
[ : ] 提取从开头到结尾的整个字符串
[ start : ] 从 start 提取到结尾
[ : end ] 从开头提取到 end - 1
[ start : end ] 从 start 提取到 end -1
[ start : end : step ] 从 start 提取到 end - 1 ,每 step 个字符提取一个;
偏移量从左至右,从 0,1 开始,依次增加;从右至左,从 -1 ,-2开始,依次减小。如果省略 start ,分片会默认使用偏移量 0 (开头);如果省略 end ,分片会默认使用偏移量 -1 (结尾)。
Python 的提取操作不包含最后一个偏移量对应的字符。
分片中 end 的偏移量需要比实际提取的最后一个字符的偏移量多 1 。
在分片中,小于起始位置的偏移量会被当作 0 ,大于终止位置的偏移量会被当作 -1 。
函数是可以执行某些特定操作的有名字的代码。与广义函数 len() 不同,有些函数只适用于字符串类型,为了调用字符串函数,需要输入字符串的名称,一个点号,接着是需要调用的函数名,以及需要传入的参数:string.function(arguments)
列表 list 是由一系列值组成的序列,值与值之间由逗号隔开,整个列表被方括号所包裹。
第三章 Python容器:列表,元组,字典,集合=============================
元组和列表都不要求所含元素的种类相同,每个元素都可以是任何Python类型的对象。元组是不可变的,当你给元组赋值时,这些值便被固定在元组里了,再也无法修改。列表却是可变的,这意味着可以随意地插入或删除其中的元素。
使用[ ] 或 list() 创建列表。列表可以由零个或多个元素组成,元素之间用逗号分开,整个列表被方括号所包裹。
如果仅仅想要记录一些互不相同的值,而不在乎它们之间的顺序关系,集合 set 会是一个更好的选择。
使用 list() 将其他数据类型转换成列表。
使用 [offset] 获取元素:和字符串一样,通过偏移量可以从列表中提取对应位置的元素。指定的偏移量小于起始位置或者大于末尾位置时,会产生异常。
列表可以包含各种类型的元素,包括其他列表。
使用 [offset] 修改元素:就像可以通过偏移量访问某元素一样,你也可以通过赋值对它进行修改。列表的偏移量必须是合法的。
通过这种方式无法修改字符串中的指定字符,因为字符串是不可变的。列表是可变的,因此你可以改变列表中的元素个数,以及元素的值。
可以使用切片提取列表的一个子序列。列表的切片任然是一个列表。列表的切片也可以设定除 1 以外的步长。
使用append() 添加元素至尾部,使用 extend() 或 += 合并列表。
del 是Python 语句,不是列表方法 -- 无法通过 marxes[-2].del() 进行调用。 del 就像是赋值语句 = 的 逆过程:它将一个Python 对象与它的名字分离。如果这个对象无其他名称引用,则其占用空间也将被清除。
判断一个值是否存在于给定的列表中有许多方式,其中最具有Python 风格的是使用 in 。同一个值可能出现在列表的多个位置,但只要至少出现一次, in 就会返回 True ;
如果经常需要判断一个值是否存在于一个列表中,但并不关心列表中元素之间的顺序,那么使用Python 集合进行存储和查找会是更好的选择。
列表方法 sort() 会对原列表进行按值排序,改变原列表的内容。
通用函数 sorted() 则会返回按值排好序的列表副本,原列表内容不变。
len() 可以返回列表长度。
如果将一个列表赋值给了多个变量,改变其中的任何一个会造成其他变量对应的值也被修改。
通过下面任意一种方法,都可以将一个列表的值复制到另一个新的列表中,复制后得到的对象是自身带有值的新对象,与原始的列表对象没有任何关联:
- 列表 copy() 函数
- list() 转换函数
- 列表分片 [ : ]
元组,与列表类似,元组也是由任意类型元素组成的序列。与列表不同的是,元组是不可变的,这意味着一旦元组被定义,将无法再进行增加,删除或修改元素等操作。因此,元组就像是一个常量列表。
使用() 创建元组,创建包含一个或多个元素的元组时,每一个元素后面都需要跟着一个逗号,即使只包含一个元素也不能省略。如果创建的元组所包含的元素数量超过 1 个,最后一个元素的逗号可以省略。
Python 的交互式解释器输出元组时会自动添加一对圆括号,但你不需要这么做,定义元组真正靠的是每个元素的后缀逗号,但如果你习惯添加一对括号也无可厚非。用括号将所有元素包裹起来,这会使程序更加清晰。
可以一口气将元组赋值给多个变量,这个过程叫 元组解包。
![](https://img2018.cnblogs.com/blog/129848/201812/129848-20181217232045868-892816386.png)
可以利用元组在一条语句中对多个变量的值进行交换,而不需要借助临时中间变量;
tuple() 函数可以用其他类型的数据来创建元组。列表转元组。
元组占用的空间较小;你不会意外修改元组的值;可以将元组用作字典的键;命名元组可以作为对象的替代;函数的参数是以元组的形式传递的。
字典,与列表类似,但其中的元素的顺序无关紧要,每个元素拥有与之对应的互不相同的键(key),需要通过键访问元素。键通常是字符串,但它还可以是 Python 中其他任意的不可变类型:布尔型,整型,浮点型,元组,字符串等;字典是可变的,因此你可以增加,删除或修改其中的键值对。
在 Python 中,字典还经常会被简写成 dict 。
使用 { } 创建字典:用大括号 { } 将一系列以逗号隔开的键值对 key : value ,包裹起来即可进行字典的创建。最简单的字典是空字典,它不包含任何键值对;
Python 允许在列表,元组或字典的最后一个元素后面添加逗号,这不会产生任何问题。此外,在大括号之间输入键值对来创建字典时并不强制缩进。
使用 dict() 转换为字典,可以用 dict() 将包含双值子序列的序列转换成字典,每个字序列的第一个元素作为键,第二个元素作为值。
任何双值子序列的序列:
- 包含双值元组的列表;
- 包含双值列表的元组;
- 双字符的字符串组成的列表;
- 双字符的字符串组成的元组;
使用 [ key ] 添加或修改元素。向字典中添加元素非常简单,只需指定该元素的键并赋予相应的值即可;如果该元素的键已经存在与字典中,那么该键对应的旧值会被新值取代。如果该元素的键并未在字典中出现,则会被加入字典中。与列表不同,你不需要担心赋值过程中 Python 会抛出越界异常。
字典的键,必须保证互不相同。
使用 update() 合并字典:使用 update() 可以将一个字典的键值对复制到另一个字典中去。如果新待添加的字典与待扩充的字典包含相同的键,新归入字典的值会取代原有的值。
使用 del 删除具有指定键的元素;
使用 clear() ,或者给字典变量重新赋值一个空字典 { } 可以将字典中所有元素删除。
使用 in 判断是否存在:如果你希望判断某一个键是否存在于一个字典中,可以使用 in 。
使用 [ key ] 获取元素:只需指定字典名和键,即可获得对应的值;如果字典中不包含指定的键,会产生一个异常。
在交互式解释器中,None 什么都不会显示。
使用 keys() 可以获得字典中的所有键。在 Python 3 中 keys() 会返回 dict_keys() ,它是键的迭代形式,如果需要一个完整的列表,你只能自己调用 list() 将 dict_keys 转换为列表类型。
在Python 3 中,你同样需要手动使用 list() 将 values() 和 items() 的返回值转换为普通的 Python 列表。
使用 values() 可以获得字典中的所有值;
使用 items() 函数可以获得字典中所有的键值对。
使用 = 赋值,使用 copy() 复制:
与列表一样,对字典内容进行的修改会反映到所有与之相关联的变量名上;
可以使用 copy() 将字典复制到一个新的字典中;
集合,就想舍弃了值,只剩下键的字典;键与键之间不允许重复。如果你仅仅想知道某一个元素是否存在而不关心其他的,使用集合是个非常好的选择。
将两个包含相同键的集合进行并操作,由于集合中的元素只能出现一次,因此得到的并集将包含两个集合所有的键,但每个键仅出现一次。空或空集,指的是包含零个元素的集合。
使用 set() 函数创建一个集合,或者用大括号将一系列以逗号隔开的值包裹起来;
和字典的键一样,集合是无序的。
由于 [ ] 能创建一个空列表,你可以期望 { } 也能创建空集,但事实上, { } 会创建一个空字典,这也是为什么交互式解释器把空集输出为 set() 而不是 { } 。
使用 set() 将其他类型转换为集合:可以利用已有列表,字符串,元组或字典的内容来创建集合,其中重复的值会被丢弃。
将字典作为参数传入 set() 函数时,只有键会被使用
使用 in() 测试值是否存在;
尽管都是由花括号 { } 包裹,集合仅仅是一系列值组成的序列,而字典是一个或多个键值对组成的序列。
3.5.4 =========================
如果想要查看多个集合之间组合的结果怎么办:可以使用交集运算符 & 。 & 交集运算符的结果是一个集合,它包含所有同时出现在你比较的两个清单中的元素。可以通过使用特殊标点符号 & 和集合函数 intersection() 获取集合的交集(两集合共有的元素)。
使用 | 或者 union() 函数来获得集合的并集(至少出现在一个集合中的元素)。
使用 - 或者 difference() 可以获得两个集合的差集(出现在第一个集合里但不出现在第二个集合里)。
使用 ^ 或者 symmetric_difference() 可以获取两个集合的异或集(仅在两个集合中出现一次)。
使用 <= 或者 issubset() 可以判断一个集合是否是另一个集合的子集(第一个集合的所有元素都出现在第二个集合中)。
当第二个集合包含所有第一个集合的元素,且仍包含其他元素时,我们称第一个集合为第二个集合的真子集,可以使用 < 进行判断。
超集与子集正好相反(第二集合的所有元素都出现在第一个集合中),使用 >= 或者 issuperset() 可以进行判断。
使用 > 可以找到一个集合的真超集(第一个集合包含第二个集合的所有元素且还包含其他元素)。一个集合并不是它本身的真超集。
使用方括号 [ ] 创建列表,使用逗号 , 创建元组,使用花括号 { } 创建字典。在每一种类型中,都可以通过方括号对单个元素进行访问。对于列表和元组来说,方括号里的内容是整形的偏移量,而对于字典来说,方括号里的是键。它们返回的都是元素的值。
字典的键必须是不可变对象,因此列表,字典和集合都不能作为字典的键,但元组可以作为字典的键。
第四章 Python 外壳:代码结构 ===========================
Python 通过代码缩进来区分代码块结构。
注释,是程序中会被 Python 解释器忽略的一段文本。在 Python 中使用 # 字符标记注释,从 # 开始到当前行结束的部分都是注释,可以把注释作为单独的一行。Python 没有多行注释,需要明确地在注释部分的每一行开始处加上一个 # 。如果 # 出现在文本串中,将 # 视为普通字符。
使用 \ 连接:可以使用 \ 连接符,把 \ 放在一行的结束位置,Python 仍然将其解释为同一行。
在 Python 表达式占很多行的情况下,行连字符也是必需的。
使用 if 、elif 和 else 进行比较:不需要在 if 判断语句中加上圆括号,但在判断的末尾要加上冒号(:)。
一般缩进四个空格。避免使用 Tab 和 Tab 与 Space 混合的缩进风格。
如果要检查超过两个条件,可以使用 if 、elif 和 else;
两个等号 == 是用来判断相等的,而一个等号 = 是把某个值赋给一个变量。
如果你想同时进行多重比较判断,可以使用布尔操作符 and 、or 或者 not 连接来决定最终表达式的布尔取值。
布尔操作费的优先级没有比较表达式的代码段高。
下面的情况都会被认为是 False :布尔 False,null 类型 None,整型 0,浮点型 0.0 ,空字符串 ' ' ,空列表 [ ] ,空元组 (),空字典 { } ,空集合 set(),剩下的都会被认为是 True 。
使用 while 进行循环;使用 break 跳出循环。
使用 continue 跳到循环开始,有时我们并不想结束整个循环,仅仅想跳到下一轮循环的开始。
使用 for 迭代:迭代器允许在数据结构长度未知和具体实现未知的情况下遍历整个数据结构,并且支持迭代快速读写中的数据,以及允许不能一次读入计算机内存的数据流处理。
列表,字符串,元组,字典,集合等都是Python 中可迭代的对象。元组或列表在一次迭代过程中产生一项,而字符串迭代会产生一个字符,对于一个字典进行迭代将返回字典中的键。如果想对字典的值进行迭代,可以使用字典的 values() 函数。为了在字典迭代时,以元组的形式返回键值对,可以使用字典的 items() 函数。
使用 break 跳出 for 循环;使用 continue 跳到下一次循环开始。for 循环也可以使用可选的 else 代码段,用来判断 for 循环是否正常结束(没有调用 break 跳出),否则会执行 else 段。当你想确认之前的 for 循环是否正常跑完,增加 else 判断是有用的。
for 循环用来遍历查找,如果没有找到则调用执行 else 。
使用 zip() 并行迭代:通过 zip() 函数对多个序列进行并行迭代,zip() 函数在最短序列“用完”时就会停止。dict() 函数会将两项序列,比如元组,列表,字符串,创建成一个字典,同时使用zip() 函数可以遍历多个序列,在具有相同位移的项之间创建元组。
使用 range() 生成自然数序列:range()函数返回在特定区间的自然数序列,不需要创建和存储复杂的数据结构。
range() 函数的用法类似于使用切片:range(start,stop,step) ,而 start 的默认值为 0。唯一要求的参数值是 stop,产生的最后一个数的值是 stop 的前一个,并且 step 的默认值是 1 ,当然,也可以反向创建自然数序列,这时 step 的值为 -1 。
像 zip() , range() 这些函数返回的是一个可迭代的对象,所以可以使用 for ... in 的结构遍历,或者把这个对象转化为一个序列。
4.6========================
推导式,是从一个或多个迭代器快速简洁地创建数据结构的一种方法。
列表推倒: [ expression for item in iterable if condition ]
字典推倒:{ key_expression : value_expression for expression in iterable },字典推倒也有if条件判断及多个 for 循环迭代语句。
集合推倒式:{ expression for expression in iterable }
元组是没有推导式的。
4.7函数===============
代码复用的第一步是使用函数。
为了定义 Python 函数,可以依次输入 def、函数名、带有函数参数的圆括号,最后紧跟一个冒号(:)。
Python 函数中的 pass 表明函数没有做任何事情。
传入到函数的值称为参数。当调用含参数的函数时,这些参数的值会被复制给函数总的对应参数。
一个函数可以接受任何数量(包括 0)的任何类型的值作为输入变量,并且返回任何数量(包括 0)的任何类型的结果。如果函数不显式调用 return 函数,难么会默认返回None。
None 是 Python 中的一个特殊的值,虽然它不表示任何数据,但仍然具有重要的作用。虽然 None 作为布尔值和 False 是一样的,但是它和 False 有很多差别。为了区分 None 和 布尔值 False ,使用 Python 的 is 操作符。
你需要把 None 和不含任何值的空数据结构区分开来, 0 值的整形 / 浮点型,空字符串(' '),空列表 [ ],空元组 ( ),空字典 { },空集合 set(),都等价于 False ,但是都不等于 None。
Python 函数的位置参数:传入参数的值是按照顺序依次复制过去的。
关键字参数:调用函数参数时,可以指定对应参数的名字,甚至可以采用与函数定义不同的顺序调用。
也可以把为位置参数和关键字参数混合起来,如果同时出现两种参数形式,首先应该考虑的是位置参数。
指定默认参数值:调用方没有提供对应的参数值时,你可以指定默认参数值。如果你提供参数值,在调用是会代替默认值。默认参数值在函数被定义时已经计算出来,而不是在程序运行时。Python 程序员经常犯的一个错误是把可变的数据类型(例如列表或字典)当作默认参数值。
当参数被用在函数内部时,星号 * 将一组可变数量的位置参数集合成参数值的元组。
使用 ** 收集关键字参数:使用两个星号可以将关键字参数收集到一个字典中,参数的名字是字典的键,对应参数的值是字典的值。
如果你把带有 *args 和 **kwargs 的位置参数混合起来,它们会按照顺序解析。
建议在函数体开始的部分附上函数定义说明的文档,这就是函数的文档字符串。
调用 Python 函数 help() 可以打印输出一个函数的文档字符串。把函数名传入函数 help() 就会得到参数列表和规范的文档。
__doc__ 是作为函数中变量的文档字符串的名字。
在 Python 中一切都是对象,包括数字,字符串,元组,列表,字典和函数。函数是 Python 中的一等公民,可以把它们(返回值)赋给变量,可以作为参数被其他函数调用,也可以从其他函数中返回值(返回函数)。
函数名是不可变的,因此可以把函数用作字典的键。
在 Python 中,可以在函数中定义另外一个函数。当需要在函数内部多次执行复杂的任务时,内部函数是非常有用的,从而避免了循环和代码的堆叠重复。
内部函数可以看做一个闭包。闭包是一个可以由另一个函数动态生成的函数,并且可以改变和存储函数外创建的变量的值。闭包:一个被动态创建的可以记录外部变量的函数。
匿名函数:lambda() 函数: 在 Python 中,lambda 函数是一个用语句表达的匿名函数。可以用它来代替小的函数。
4.8================
生成器,是用来创建 Python 序列的一个对象,通常,生成器是为迭代器产生数据的。
如果你想创建一个比较大的序列,使用生成器推导的代码会很长,这时可以尝试写一个生成器函数。生成器函数和普通函数类似,但是它的返回值使用 yield 语句声明而不是 return 。
装饰器:有时你需要在不改变原有源代码的情况下修改已经存在的函数。装饰器,实质上是一个函数,它把一个函数作为输入并且返回另外一个函数。在装饰器中,通常使用下面这些 Python 技巧: *arg 和 **kwargs,闭包,作为参数的函数。
命名空间和作用域:Python 程序有各种各样的命名空间,它指的是在该程序段内一个特定的名称是独一无二的。
每一个函数定义自己的命名空间(局部命名空间)。如果在主程序中定义一个变量 x ,在另外一个函数中也定义 x 变量,两者指代的是不同的变量。
每个程序的主要部分定义了全局命名空间,因此,在这个命名空间的变量是全局变量。
可以在函数内部得到全局变量的值,但是,如果想在函数中修改全局变量的值,会报错。为了在函数中读取并修改全局变量,需要在变量前面显式地添加关键字 global (在单独一行中添加)。
Python 提供了两个获取命名空间内容的函数:
- locals() 返回一个局部命名空间内容的字典;
- globals() 返回一个全局命名空间内容的字典。
使用 Python 内嵌函数(内建函数) id() 打印输出每个对象的唯一的 ID 值;
名称中 _ 和 __ 的用法: 一个函数的名称是系统变量 function.__name__,函数的文档字符串是 function.__doc__,主程序的名字是 __main__ 。
使用 try 和 except 处理错误:Python 中的异常,是一段只有错误发生时执行的代码。
当你执行可能出错的代码时,需要适当的异常处理程序用于阻止潜在的错误发生。
在 try 中的代码块会被执行,如果存在错误,就会抛出异常,然后执行 except 中的代码,否则,跳过 except 块代码。
可以使用下面的格式获取整个异常对象: except exceptiontype as name