第一章:用Pythonic方式来思考(总结)

第1条:确认自己所用的Python版本

书中提到了两种方式:

第1种:用 --version标志来运行python命令,来查看所使用的具体Python版本。

第2种:以代码的方式查询,在内置的sys模块里查询相关的值,来确定我们当前使用的Python版本。

总结:Python3和Python2有较大差异,不要纠结学2还是3,因为Python社区已经给出了答案,Python社区把开发重点放在Python3上,Python2的功能开发已经冻结,只会进行bug修复及维护工作,以便开发者能够顺利的从Python2迁移到Python3。所以学3。

第2条:遵循 PEP 8 风格指南

《Python Enhancement Proposal #8》又叫PEP 8,它是针对Python代码格式而编订的风格指南.
作者推荐大家应该把整份指南都读一遍(https://www.python.org/dev/peps/pep-0008/),所以就不做过多的讲解了。

总结:当编写Python代码时,总是应该遵循 PEP 8风格指南。

第3条:了解bytes、str与unicode的区别

Python3 两种字符串类型:bytes和str,bytes表示8-bit的二进制值(即每个字节有8个二进制位),str表示unicode字符

Python2 两种字符串类型:str和unicode,str表示8-bit的二进制值(即每个字节有8个二进制位),unicode表示unicode字符

注意:在Python3中,通过内置的open函数获取文件,Python3默认采用UTF-8编码格式来操作文件,而Python2默认编码格式是二进制形式。

总结:
    1.要想把Unicode字符转换成二进制数据,就必须使用encode方法。要想把二进制数据转换为Unicode字符,则必须使用decode方法。
    2.Python3中开发者不能在bytes和str实例之间以 > 或 +来操作。
    3.Python2中如果str只含有7-bit的二进制值(即每个字节有7个二进制位),那么可以通过相关操作符来同时使用str和unicode。
    4.从文件中读取二进制数据,或向其中写入二进制数据时,总应该以"rb"或"wb"等二进制模式来开启文件。

第4条:用辅助函数来取代复杂的表达式

总结:由于Python的语法特性使得开发者很容易过度的运用,从而写出特别复杂的表达式并且难以理解,所以,本条推荐我们将复杂的表达式移入到辅助函数,可以理解为将复杂的表达用条理清晰的语法写到函数,即所谓的封装,这样不仅代码可读性高,也提高了代码的重用性。

第5条:了解切割序列的办法

这种切割序列的方法,也称为切片操作或切割操作,切片操作可以使我们能够轻易的拿到序列中的元素。切片操作在代码中出现的次数并不多,但是非常实用。

切片操作的基本语法somelist[start🔚stride],其中start(起始索引),end(结束索引),stride(步长),这里是左开右闭原则即截取包含start对应的元素,不包含end对应的元素。

总结:
    1.如果从列表头开始切片,start可以省略,如果从一直截取到列表末尾,则end可以省略。
    2.切割列表时,即便start或end索引越界也不会出问题。
    3.如果想从列表尾部向前截取则可以使用负值来表示。
    4.对list赋值时,如果使用切片操作,则不会考虑长度是否一致而会整个替换。

第6条:在单次切片操作内,不要同时指定start、end和stride

总结:
    1.这条的目的主要是怕代码难以阅读,如果要同时指定,作者建议将其拆解为两条赋值语句,一条做范围切割,另一条做步进切割。
    2.尽可能的避免在切片中使用负数值做stride。

第7条:用列表推导来取代map和filter

列表推导式也是很实用的一种写法。是Python提供的一种精炼的写法。我就非常喜欢这种写法。

总结:
    1.列表表达式比内置的map,filter更加清晰,因为map,filter需要额外的lambda表达式(匿名函数)的支持。
    2.字典和集合也都支持列表表达式。

第8条:不要使用含有两个以上表达式的列表推导

总结:列表表达式支持多层的循环和条件语句,每层循环也支持多项条件。但是当列表表达式内部有超过两个表达式的时候就会变得难于阅读,这种写法应该避免使用。

第9条:用生成器表达式来改写数据量较大的列表推导

列表推导的缺点就是在推导过程中会给输入序列中的每个值创建一个仅包含该元素的序列。所以当输入的数据非常多的时候,那么就可能会消耗大量内存,导致程序崩溃。为了解决此问题,Python提供了生成器表达式,写法很简单,把实现列表推导式所用的那种写法放在一对圆括号中,就构成了生成器表达式。它会立刻返回一个迭代器,已返回的迭代器为参数,逐次调用内置的next函数即可。

总结:当输入的数据量较大时,应使用生成器表达式

第10条:尽量用enumerate取代range

在一系列整数上面迭代,内置的range函数很有用,但是在迭代列表元素的同时并想输出对应元素的索引时,用enumerate函数就再合适不过了。

总结:
    1.enumerate提供了简洁的语法,再循环迭代一个迭代器的同时既能获取下标,也能获取当前值。
    2.可以添加第二个参数来指定 索引开始的序号,默认为0。

第11条:用zip函数同时遍历两个迭代器

zip函数也是一个非常好的函数,语法就不详细讲解了。简单的总结下zip函数吧

总结:
   1.zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
   2.zip()在 Python 2 和 Python 3 中的不同:在 Python 3中为了减少内存,zip相当于生成器,会在遍历过程中逐次产生元组。如需展示列表,需手动 list() 转换。而Python2中的zip则直接把这些元组直接生成好,并一次性返回整份列表。

第12条:不要在for和while循环后面写else块

Python提供了一种很多编程语言都不支持的功能,就是可以在循环内部的语句块后面直接编写else块,这是基本语法不多解释,本条不推荐在循环内部写else块。

总结:不要在循环后面写else块,因为这种写法不直观,又容易引人误解。

第13条:合理利用try/except/else/finally 结构中的每个代码块

try/except/else/finally 可以在Python程序中的不同时机使用,每块都有特定的用途,这是基本语法不多解释,这里讲一下else块,else块可以用来缩减try块中的代码量,并把没有发生异常时所需要执行的语句与try/except代码块分隔开。

总结:基本语法没有什么可以总结的。