“条件与循环”,是 Python 编程中的基本功。它控制着代码的逻辑,把列表、元祖、字典、集合和字符串等一系列 Python 的基本数据类型串接起来,可以说是程序的中枢系统。如果把写程序比作盖楼房,那么条件与循环就是楼房的根基,其他所有东西都是在此基础上构建而成。毫不夸张地说,写一手简洁易读的条件与循环代码,对提高程序整体的质量至关重要。
Python 的条件语句
1.和其他语言不一样,我们不能在 Python 条件语句中加括号。而且需要注意的是,在条件语句的末尾必须加上冒号(:),这是 Python 特定的语法规范。
if (x < 0) # 错误写法
if x < 0: # 正确写法
2.Python 不支持 switch 语句,因此,当存在多个条件判断时,我们需要用 else if 逻辑来实现,这在 Python 中的表达是 elif。整个条件语句是顺序执行的,如果遇到某一个条件满足,比如 condition_i 满足时,在执行完 statement_i 后,便会退出整个 if、elif、else 条件语句,而不会继续向下执行。不过要注意,if 语句是可以单独使用的,但 elif、else 都必须和 if 成对使用。
if condition_1:
statement_1
elif condition_2:
statement_2
...
elif condition_i:
statement_i
else:
statement_n
实际上,Python 中并不要求 if-elif 结构后面必须有 else 模块,else 是一条包罗万象的语句,只要不满足任何 if 或者 elif 中的条件测试,就会执行else中的代码,这可能会引入无效或恶意的数据。如果知道最终要测试的条件,应考虑使用一个 elif 代码块来替代 else 代码块。
3.在进行条件判断时, 不少人喜欢省略判断的条件,省略判断条件的常见用法如下:
不过,在实际写代码时,还是鼓励除了 boolean 类型的数据,条件判断最好是显性的。比如,在判断一个整型数是否为 0 时,我们最好写出判断的条件:
if i != 0:
...
# 而不是只写出变量名:
if i:
...
Python 的循环语句
所谓循环,顾名思义,本质上就是遍历集合中的元素。和其他语言一样,Python 中的循环一般通过 for 循环和 while 循环实现。
- 只要是可迭代的数据类型(iterable),比如列表、集合等等,那么都可以通过下面这种方式遍历:
for item in <iterable>:
...
- 而字典本身只有键是可迭代的,要遍历它的值或者是键值对,就需要通过其内置的函数 values() 或者 items() 实现。其中,values() 返回字典的值的集合,items() 返回键值对的集合。
d = {'name': 'jason', 'dob': '2000-01-01', 'gender': 'male'}
for k in d: # 字典本身只有键是可迭代的
print(k)
name
dob
gender
for v in d.values(): # values()遍历字典的值
print(v)
jason
2000-01-01
male
for k, v in d.items(): # items()遍历字典的键值对
print('key: {}, value: {}'.format(k, v))
key: name, value: jason
key: dob, value: 2000-01-01
key: gender, value: male
- 也通过索引来遍历元素,甚至很多时候,我们还得根据索引来做一些条件判断。通常是通过 range() 这个函数,拿到索引,再去遍历访问集合中的元素。
l = [1, 2, 3, 4, 5, 6, 7]
for index in range(0, len(l)):
if index < 5:
print(l[index])
1
2
3
4
5
- 当我们同时需要索引和元素时,还有一种更简洁的方式,那就是通过 Python 内置的函数 enumerate()。用它来遍历集合,不仅返回每个元素,并且还返回其对应的索引。
l = [1, 2, 3, 4, 5, 6, 7]
for index, item in enumerate(l):
if index < 5:
print(item)
1
2
3
4
5
- 循环语句中还常常搭配 continue 和 break 一起使用。所谓 continue,就是让程序跳过当前这层循环,继续执行下面的循环;而 break 则是指完全跳出所在的整个循环体。在循环中适当加入 continue 和 break,往往能避免多层嵌套的情况,使程序更加简洁、易读。
- 对于 while 循环,它表示当 condition 满足时,一直重复循环内部的操作,直到 condition 不再满足,就跳出循环体。
- 很多时候,for 循环和 while 循环可以互相转换。两者使用场景的区别是:如果只是遍历一个已知的集合,找出满足条件的元素,并进行相应的操作,那么使用 for 循环更加简洁。但如果需要在满足某个条件前,不停地重复某些操作,并且没有特定的集合需要去遍历,那么一般则会使用 while 循环。
# while循环
i = 0
while i < 1000000:
i += 1
# 等价的 for循环
for i in range(0, 1000000):
pass
同时,需要注意的是,for 循环和 while 循环的效率问题。上述代码中,range() 函数是直接由 C 语言写的,调用它速度非常快。而 while 循环中的“i += 1”这个操作,得通过 Python 的解释器间接调用底层的 C 语言;并且这个简单的操作,又涉及到了对象的创建和删除(因为 i 是 int 型,是 immutable(不可变数据类型),i += 1 相当于 i = new int(i + 1))。所以,显然,for 循环的效率更胜一筹。
条件与循环的复用
在阅读代码的时候,你应该常常会发现,有很多将条件与循环并做一行的操作,例如:
expression for item in iterable if condition
# 等同于下面这样的嵌套结构
for item in iterable:
if condition:
expression
# 加入 else代码块
expression1 if condition else expression2 for item in iterable
# 等同于下面这样的嵌套结构
for item in iterable:
if condition:
expression1
else:
expression2
当然,这样的复用并不仅仅局限于一个循环。比如,给定两个列表 x、y,要求返回 x、y 中所有元素对组成的元组,相等情况除外。
[(xx, yy) for xx in x for yy in y if xx != yy]
# 等价于下面这样的嵌套结构
l = []
for xx in x:
for yy in y:
if xx != yy:
l.append((xx, yy))
这种写法非常方便。当然,如果遇到逻辑很复杂的复用,可能写成一行难以理解、容易出错。这种情况下,用正常的形式表达,也不失为一种好的规范和选择。
小结
重点强调几个易错的地方:
- 在条件语句中,if 可以单独使用,但是 elif 和 else 必须和 if 同时搭配使用;而 If 条件语句的判断,除了 boolean 类型外,其他的最好显示出来。
- 在 for 循环中,如果需要同时访问索引和元素,你可以使用 enumerate() 函数来简化代码。
- 写条件与循环时,合理利用 continue 或者 break 来避免复杂的嵌套,是十分重要的。
- 要注意条件与循环的复用,简单功能往往可以用一行直接完成,极大地提高代码质量与效率。
参考
《Python核心技术与实战》