python优化else_python 中 难以理解的for-else语句

老婆给当程序员的老公打电话:“下班顺路买一斤包子带回来,如果看到卖西瓜的,买一个。”当晚,程序员老公手捧一个包子进了家门……老婆怒道:“你怎么就买了一个包子?”老公答曰:“因为看到了卖西瓜的。”

程序员买西瓜的笑话可能大部分读者都知道,今天写的这篇文章和这个笑话有一定的关系。

任何编程语言都提供了 if…else… 语句,表示如果(if)满足条件就做某件事,否则(else)就做另外一件事:

Python

if a==b:

print("true")

else:

print("false")

1

2

3

4

ifa==b:

print("true")

else:

print("false")

然而,在 Python 中 else 不仅可以和 if 搭配使用,还有另一种特有的句法是 for…else …,除此之外,它还可以和 while、try…except 组合使用,例如:

Python

for i in range(3):

print(i)

else:

print("end")

>>>

0

1

2

end

1

2

3

4

5

6

7

8

9

foriinrange(3):

print(i)

else:

print("end")

>>>

0

1

2

end

但是,你会发现 for…else… 与 if…else… 表现得不一样,按照以往经验来说,执行了 for 语句块中的代码就不执行 else 里面的,反之亦然。

然而,我们看到的却恰恰相反,for 循环结束之后接着又执行了 else 语句块,这就有点意思了,if … else … 翻译成白话就是 如果…否则…,而 for…else… 翻译成白话成了 直到… 然后 …,为什么不把它写成 for…then… 的句式呢?这不更好理解吗?

另外,即使 for 循环遍历的是一个空列表也会执行 else 语句块。

Python

for i in []:

print(i)

else:

print("end")

>>>

end

1

2

3

4

5

6

foriin[]:

print(i)

else:

print("end")

>>>

end

继续探索,如果我们用 break 提前终止 for 循环,会发生什么?

Python

for i in range(3):

print(i)

if i % 2 == 0:

break

else:

print("end")

>>>

0

1

2

3

4

5

6

7

8

foriinrange(3):

print(i)

ifi%2==0:

break

else:

print("end")

>>>

0

循环遇到 break 退出后,整个语句就结束,else 语句块也不执行了。

综上,我们可以得出这样一个结论,只有当循环里没有遇到 break 时,else 块才会执行。此刻,你应该明白了,真正和 else 搭配使用的是 for 循环中的 break,break … else … 才是两个互斥的条件

Python 之父为什么要搞出这样的一种语法糖出来呢?这是我们常人没法理解的。不过「

"Although that way may not be obvious at first unless you're Dutch."。

在平时的开发中真的很少有 for…else… 的应用场景,不过,像下面这种场景用 for else 还真是一种 pythonic 的用法。

当你用 for 循环迭代查找列表的中的某个元素时,如果找到了就立刻退出循环,如果迭代完了列表还没找到需要以另外一种形式(比如异常)的方式通知调用者时,用 for…else… 无疑是最好的选择。

Python

# https://stackoverflow.com/a/9980752/1392860

for i in mylist:

if i == target:

break

process(i)

else:

raise ValueError("List argument missing terminal flag.")

1

2

3

4

5

6

7

# https://stackoverflow.com/a/9980752/1392860

foriinmylist:

ifi==target:

break

process(i)

else:

raiseValueError("List argument missing terminal flag.")

如果不用 for…else… , 那么还需要专门建立一个临时标记变量来标记是否已经找到了

Python

found = False

for i in mylist:

if i == target:

found = True

break

process(i)

if not found:

raise ValueError("List argument missing terminal flag.")

1

2

3

4

5

6

7

8

found=False

foriinmylist:

ifi==target:

found=True

break

process(i)

ifnotfound:

raiseValueError("List argument missing terminal flag.")

当你想在房间里找某样东西时,只要在任意位置找到了,就停止继续搜查工作。但如果把整个房间都翻遍了,还没找到我们想要的东西时,需要告诉人家,很抱歉,这儿没有你要找的东西。遇到这样的情况时就用 for … else ,除此之外,恐怕只会引起误操作。

2018-05-29-012523.png

2020012309512985.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值