python高效59则(Effective Python)-第一
2019-01-15 本文已影响0人
鼻子两个孔
读《Effective Python》的记录
- 确认合适的版本,优先考虑python3
- 遵循PEP9风格指南
- 函数、变量及属性用小写字母来拼写,各单词之间下划线连接
- 类与异常,首字母大写,无下划线
- 否定词放后面,if a is not b
- if somelist会自动判断是否为空,不需要求len(somelist)
- ……
- bytes、str和unicode。
- python3包括bytes和str,bytes为原始的8位数
- python2包括str和unicode,str为原始的8位数
- encode:把unicode转换为二进制数据
- decode:把二进制数据转换为unicode
- python3读取文件时默认是utf-8格式,如果要读取二进制,需要用rb、wb
- 使用函数来代替复杂的表达式
- 切片(slice)
- somelist[start:end]
- 如果是0或者末尾,可以省略
- 单次切片操作,不要同时指定start,end和stride。
- odds = a[::2],evens=a[1::2]
- y = x[::-1]反转
- 对utf-8的无效
- 用列表来替代map和filter
- a = [1,2,3,4,5,6],squares=[x**2 for x in a]
- 可以使用if,even_squares=[x**2 for x in a if x % 2 == 0]
- dict和set也支持
- 不要使用两个或以上表达式来列表推导,超过两个表达式的列表推导很难理解,要避免
- 用生成器表达式来改写数据量较大的列表推导
- 第7点如果数据量太大的时候,会消耗大量内存,只适合少量的输入值。大文件需要用到generator expression
- value = [len(x) for x in open("filename")],这是列表推导
- value = (len(x) for x in open("filename")),这是生成器表达式,逐次调用内置的next(value),不用担心内存。
- 用enumerate取代range。如果需要知道列表中的索引,可以用获取list长度后使用range。而enumerate可以把各种迭代器包装为生成器,循环下标.
flavor_list = ["a","b","c","d","e"]
# 使用range
for i in range(len(flavor_list)):
flavor = flavor_list[i]
print('%d,%s'%(i,flavor)
# 使用enumerate
for i,flavor in enumerate(flavor_list):
print('%d,%s'%(i,flavor)
# enumerate还提供第二个参数,指定开始计数时的值(默认为0)
for i,flavor in enumerate(flavor_list,1):
print('%d,%s'%(i,flavor)
- 用zip函数同时遍历两个迭代器。对于相关联的两个list
names = ["Karry","Roy","Jackson"]
letters = [len(n) for n in names]
longest_name = None
max_letters = 0
# 平行迭代两个list
for i in range(len(names)):
count = letter[i]
if count > max_letters:
longest_name = names[i]
max_letters = count
print(longest_name)
# 使用enumerate
for i,name in enumerate(names):
count = letter[i]
if count > max_letters:
longest_name = names[i]
max_letters = count
# 使用内置的zip函数
for name,count in zip(names,letters):
if count > max_letters:
longest_name = names
max_letters = count
- python2不适合用于大文件,会占内存,因为python2是直接返回整份列表
- 如果两个迭代器长度不同,自动终止
- 不要在for和while循环后写else,既不直观又容易让人误解
- 合理利用try/except/else/finally结构中的每个代码块
- finally,将异常向上传播的同时执行清理工作,finally的内容必须要在try的前面
- else,try/except/else,如果try没有异常就进行else,可以缩短try的代码量
- 混合使用,如果某些操作需要在finally之前执行,写到else块中