《Effective Python 编写高质量Python代码的59个有效方法》学习笔记2

尽量用enumerate取代range

#当需要循环的是数值时可以使用range()
for x in range(10):
    pass
#或者获取列表元素时可直接迭代
food = ['apple','egg','rice']
for x in food:
    pass

#而当需要元素所在索引时,一般我们用
for x in range(len(food)):
    pass

#这样很生硬

'''
Python内置函数enumerate()可把各种迭代器(包括各种序列及各种支持迭代的对象)包装为生成器
每次产生一对输出值,前者表示循环下标,后者表示从迭代器中获取到的下一个序列元素
同时可以有第二个参数,指明开始计数的索引值,默认为0
'''

for i,food in enumerate(food):
    print i,food
#输出
#0 apple
#1 egg
#2 rice

for i,food in enumerate(food,2):
    print i,food
#输出
#2 apple
#3 egg
#4 rice

用zip()同时遍历两个迭代器

names = ['tom','jack','jy']
letters = [len(n) for n in names] #注意这里列表推导用法

#要获取最长的名字及其长度多少
longest_name = None
max_letter = 0

#常规做法 、看上去比较混乱 不易阅读
for i in range(len(names)):
    count = letters[i]
    if count > max_letter:
        longest_name = names[i]
        max_letter = count

#使用zip
for name,count in zip(names,letters):
    if count > max_letter:
        longest_name =name
        max_letter = count

'''
当遍历的两个迭代器长度不同时,会在最短的那里停止
python3中zip相当于生成器,会在遍历时逐次产生元组
'''

合理使用try-except-else-finally

如果既要异常向上传播,又要在异常发生时执行清理工作,可使用try/finally结构
try/except/else结构可以清晰描述哪些异常由自己的代码处理,哪些传播到上一级
无论try块是否异常,都可用try/finally复合语句的finall块执行清理工作
else块可缩减try中代码量,并把没有异常时要执行的语句与try/except隔离开
顺利运行try后,若想使某些操作能在finally块的清理代码之前执行,则可将这些操作写到else块中

使用异常表示特殊情况而不要返回None

用None作返回值来表示特殊意义的函数,很容易使调用者犯错,因为None和0及空字符串之类的值,在条件表达式中都会被评估为False。
函数在遇到特殊情况时,应该抛出异常,而不要返回None.调用者在看到该函数的文档中所描述的异常后,应该就会编写相应的代码来处理了。

闭包里使用外围作用域中的变量

#对list排序,但是要把出现在某个列表中的数字排在其他数字之前


def sort_priority(values,group):
    def helper(x):
        if x in group:
            return (0,x)
        return (1,x)
    values.sort(key=helper)

numbers = [8,3,1,2,5]
group = {2,3,5}
sort_priority(numbers,group)
print(numbers)
#>>[2, 3, 5, 1, 8]
'''
python支持闭包(closure):闭包是一种定义在某个作用域中的函数,它引用了那个作用域里的变量。
helper之所以能访问sort_priority的group参数,原因在于它是闭包
python函数是一级对象,即可直接引用函数、把函数赋给变量、把函数当成参数传给其他参数,并通过表达式及if语句对其进行比较和判断。
所以这里可以把helper这个闭包函数传给sort的key参数
python使用特殊的规则比较两个元组。首先比较各元组中下标为0的对应元素,如果相等,再比较下标为1 的对应元素...以此类推
'''

##########获取闭包内的数据
###【python3】###
#nonlocal语句的意思是在给相关变量赋值时应在上层作用域中查找该变量 / 唯一限制在于不能延伸到模块级别,防止污染全局作用域
#与global相对
def sort_priority3(numbers,group):
    found = False
    def helper(x):
        nonlocal found
        if x in group:
            found = True  #表示是否出现了优先级更高的元素。使函数调用者能够做出相应处理
            return (0,x)
        return (1,x)
    numbers.sort(key=helper)
    return found
    #为了防止滥用,只推荐在很简单的函数里使用nonlocal

#新浪面试题
li = [lambda :x for x in range(10)]
print(type(li))
print(type(li[0]))
# <class 'list'>
# <class 'function'>

res = li[0]()
print(res)
#输出:9
#函数在没有执行前,内部代码不执行
#因为x最后循环成了9,所以每一个return x出来的值都是9
'''
Python中是没有块级作用域的,代码块里的变量,外部可以调用;
即使执行了一下函数,name的作用域也只是在函数内部,外部依然无法进行调用
'''
##【关于函数名】##
'''
假如定义了函数f1()
那么访问f1(),就会得到f1()中的返回值
访问f1,就会得到f1函数的内存地址
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值