一次由 python for、while-else 语法糖引发的深度学习


故事

昨儿,一天迷离。

手忙脚乱,写了一段代码;
误打误撞,通过了测试用例;
迷迷糊糊,提交入库了。

今儿醒来 review, 觉得是 bug, 结果却获得了意外…

因此就有了这个,一次由 python for/while-else 「 语法糖 」 引发的 「 深度学习 」。

故事开头是这样的:

判断一个「 , 」分割的字符串,如果是 None,则返回「 * 」;如果不是,则遍历验证每一个元素是否在列表中,不存在则错误输出,存在则返回列表。

非常简单的逻辑,可我写成了这个样子:

Python loop with else Question

写过一段 C/C++ 或者 Java 的我,review 时看到这个,瞬间懵逼了。

bug 呀,那个 else 不应该出现呀,缩进应该往前提一下呀,语法错误呀…

可是测试用例的处理逻辑却跑的没问题呀,二脸懵逼…

赶紧 Google…

Python for/while-else 语法

搜索文档才发现:

Python loop with else doc

Python 的 for…else 和 while…else 语法,是 Python 中最不常用、最为误解的语法特性之一。

Python 中的 for、while 循环都可以有一个可选的 else 分支(类似 if 语句和 try 语句那样),在循环迭代正常完成之后执行。也就是说,如果我们不是以非正常方式以外的其他任意方式退出循环,那么 else 分支将被执行。也就是在循环体内没有 break 语句、没有 return 语句,或者没有异常出现。

那么,写一个 demo 测试一下这个语法糖吧。

Demo 测试

把代码写成这样,验证一下这个语法糖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# coding=utf-8


"""
# test_loop_with_else.py
#
# Copyright(C) By AbsentM. 2018
#
# Author: AbsentM
# Date: 2018/03/18
#
# Description: Test python loop with else demo
#
# Change Log:
# 2018/03/18 AbsentM Create the file
# 2018/03/18 AbsentM Add test demo
#
"""

def run_for_else_validation(fruits):
"""
Test python for else
:param fruits: A string of fruits split with ','
"""
if fruits is None:
fruits_result = "*"
else:
fruits = fruits.split(",")
print "fruits >>> {}".format(fruits)

for item in fruits:
print "item >>> {}".format(item)
else:
fruits_result = fruits

print "total >>> {}".format(fruits_result)


def run_while_else_validation():
"""
Test python while else
"""
index = 0
while index <= 10:
index += 1
print "index {}: {} ".format(index, index)
else:
print "in while else"


if __name__ == '__main__':

print "---------------------------"
print "Run first test..."
test_1 = None
run_for_else_validation(test_1)
print "Run first test finished"

print "---------------------------"
print "Run second test..."
test_2 = "apple"
run_for_else_validation(test_2)
print "Run second test finished"

print "---------------------------"
print "Run third test..."
test_3 = "apple,pear,orange"
run_for_else_validation(test_3)
print "Run third test finished"

print "---------------------------"
print "Run fourth test..."
run_while_else_validation()
print "Run fourth test finished"

输出的结果是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
---------------------------
Run first test...
total >>> *
Run first test finished
---------------------------
Run second test...
fruits >>> ['apple']
item >>> apple
total >>> ['apple']
Run second test finished
---------------------------
Run third test...
fruits >>> ['apple', 'pear', 'orange']
item >>> apple
item >>> pear
item >>> orange
total >>> ['apple', 'pear', 'orange']
Run third test finished
---------------------------
Run fourth test...
index 1: 1
index 2: 2
index 3: 3
index 4: 4
index 5: 5
index 6: 6
index 7: 7
index 8: 8
index 9: 9
index 10: 10
index 11: 11
in while else
Run fourth test finished
[Finished in 0.3s]

完整代码地址:python-loop-with-else-demo

庆幸每一次懵逼后的不知所措
庆幸每一次 fix 后的醍醐灌顶。

参考资料

[1] https://docs.python.org/2/tutorial/controlflow.html#for-statements
[2] http://book.pythontips.com/en/latest/for_-_else.html
[3] http://python.jobbole.com/81063/


END

0%