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


    核心知识点:

    (1)一般的if/else是前面不执行,后面才执行,循环下面的else是前面执行完后面才会执行,如果是break打断也不会执行。循环为空或False也不执行。

    (2)try/expect是前面不执行后面才会执行,try/expect/else是try执行成功才会执行else,也就是expect不执行;try/finally不管前面是否执行后面都会执行。

    (3)不要在循环后面使用else,这会让人很费解。

    Python提供了一种很多编程语言都不支持的功能,那就是可以在循环内部的语句后面直接编写else。

    >>> for i in range(3):
    ...     print('Loop %d' % i)
    ... else:
    ...     print('Else block!')
    ...
    Loop 0
    Loop 1
    Loop 2
    Else block!

    奇怪的是,这种else块会在整个循环执行完之后立刻执行。既然如此,那为什么叫做else呢?为什么不叫and?

    在if/else语句中,else的意思是:如果不执行前面那个if块,那就执行else块。

    在try/expect语句中,expect的定义也类似:如果前面那个try块没有成功执行,那就执行expect块。

    同理,try/expect/else也是如此,该结构的else含义是:如果前面的try块没有失败,那就执行else。

    try/finally的意思是:执行过前面的try块之后,总是执行finally块。

    明白了else、expect和finally的含义之后,刚接触Python的程序员可能会把for/else结构中的else理解为:

    如果循环没有正常执行完,那就执行else块。实际上刚好相反——在循环里用break语句提前跳出,会导致程序不执行else块。

    >>> for i in range(3):
    ...     print('Loop %d' % i)
    ...     if i == 1:
    ...         break
    ... else:
    ...     print('Else block!')
    ...
    Loop 0
    Loop 1   #没有执行else

    还有一个奇怪的地方:如果for循环要遍历的序列是空的,那么就会立刻执行else块。

    >>> for x in []:
    ...     print('Never runs')
    ... else:
    ...     print('For Else block!')
    ...
    For Else block!

    初始循环条件为false的while循环,如果后面跟着else,那它也会立刻执行。

    >>> while False:
    ...     print('Never runs')
    ... else:
    ...     print('While Else block!')
    ...
    While Else block!

    知道了循环后面的else块所表现出的行为之后,我们会发现:在搜索某个事物的时候,这种写法是有意义的。

    >>> a = 4
    >>> b = 9
    >>> for i in range(2,min(a,b) + 1):
    ...     print('Testing',i)
    ...     if a % i == 0 and b % i == 0:
    ...         print('Not coprime')
    ...         break
    ... else:
    ...     print('Coprime')
    ...
    Testing 2
    Testing 3
    Testing 4
    Coprime

    上面的式子可以判断两个数是否有除了1之外的公约数,如果有,则不会打印Compire,如果没有,就会打印Compire。

    实际上,我们不会这样写代码,而是会用辅助函数来完成计算,这样的辅助函数有两种常见的写法。

    第一种写法是,只要发现受测参数符合自己想要搜寻的条件,就尽早返回。如果整个循环都完整地执行了一遍,那就说明受测参数不符合要求,于是返回默认值。

    >>> def coprime(a,b):
    ...     for i in range(2,min(a,b) + 1):
    ...         if a % i == 0 and b % i == 0:
    ...             return False
    ...     return True

    第二种写法是,用变量来记录首测参数是否符合自己想要搜寻的条件。一旦符合,就用break跳出循环。

    >>> def coprime2(a,b):
    ...     is_coprime == True
    ...     for i in range(2,min(a,b) + 1):
    ...         if a % i == 0 and b % i == 0:
    ...             is_coprime == False
    ...             breake
    ...     return is_coprime  #这种方法只是上面那一种方法的升级版

    对于不熟悉for/else的人来说,这两种写法都要比早前那种写法清晰很多。

    for/else结构中的else块虽然也能够实现相应的功能,但是会令阅读代码的人相当不解,因为它不是属于常规逻辑。

    像循环这种简单的语言结构,在python程序中应该写得非常直白才对,我们完全不应该在循环的后面使用else块

    文章摘抄于Brett Slatkin的《编写高质量Python代码的59个有效方法》,仅作为个人学习使用,如有侵权请告知,将及时删除,如果觉得有益,请购买原版书籍,知识需要传递和支持,谢谢。

  • 相关阅读:
    Python自动化学习笔记(九)——Python的面向对象
    Python自动化学习笔记(八)——接口开发、发送网络请求、发送邮件、写日志
    MRWordCount
    环境变量追加命令
    hadoop退役旧数据节点
    Hadoop服役新数据节点
    Namenode文件损坏
    NameNode故障处理
    NN和2NN工作机制
    hdfs读写流程
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/8025557.html
Copyright © 2020-2023  润新知