Python进阶指南

条件表达式

条件语句通常用于在两个值之间进行二选一,例如:

1
2
3
4
5
x, y = 50, 25
if x < y:
small = x
else:
small = y

当然数值比较取最小值应该用min函数,此处只作为讲解例子,我们可以用条件表达式化简这个语句:

1
2
x, y = 50, 25
small = x if x < y else y

条件表达式语法如下:

[on_true] if [expression] else [on_false]
如果[expression]为True,则表达式的值为[on_true],否则为[on_false]。

有时候也可以使用条件表达式改写递归函数。例如,下面是阶乘函数的递归版本:

1
2
3
4
5
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)

我们可以像这样重写:

1
2
def factorial(n):
return 1 if n == 0 else n * factorial(n-1)

一般来说,如果条件语句的两个分支中均为简单的表达式,不是被返回就是被赋值给相同的变量,那么此时可以考虑用条件表达式。

推导式

列表推导式(list comprehension)

列表推导式(list comprehension)可以使用非常简洁的方式来快速生成满足特定需求的列表,代码具有非常强的可读性,常用来转换和过滤数据。

语法如下:

[表达式 for 变量 in 列表 if 条件]

转换数据

比如创建一个平方数列表:

1
2
3
4
5
6
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

用列表推导式:

1
squares = [x**2 for x in range(10)]

当然,这也等价于squares = map(lambda x: x**2, range(10)),但是列表推导式更清晰可读。

过滤数据

比如得到偶数列表:

1
2
>>> [x for x in range(10) if x%2 == 0]
[0, 2, 4, 6, 8]

集合推导式(set comprehension)

如果列表推导式的结果里有很多重复项的话,可以使用集合推导式,语法就是把列表推导式外面的方括号换为花括号,如:

1
2
>>> {x**2 for x in [1,1,2,3]}
set([1, 4, 9])

字典推导式(dict comprehension)

字典推导式也是用花括号,只不过是key:value的形式。比如下面代码互换字典的key和value:

1
2
3
>>> d = {"a":1, "b":2, "c":3, "d":4}
>>> {v:k for k,v in d.items()}
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}

生成器表达式(generator expression)

生成器表达式是列表推导式的生成器版本,使用的是圆括号,而不是方括号:

1
2
3
>>> g = (x**2 for x in range(5))
>>> g
<generator object <genexpr> at 0x026258F0>

结果是一个生成器对象,该对象知道如何遍历一个值序列。但与列表推导式不同的是,它不会一次性计算出所有的值;而是等待求值请求。内建函数next从生成器获取下一个值:

1
2
3
4
>>> next(g)
0
>>> next(g)
1

抵达序列的末尾时,next 会抛出StopIteration 异常。你还可以使用 for 循环遍历这些值:

1
2
3
4
5
>>> for val in g:
... print(val)
4
9
16

生成器对象会记录其在序列中的位置,因此 for 循环是从 next 结束的地方开始的。一旦生成器被消耗完,它会抛出 StopException,因此:生成器只能遍历一次 。

1
2
>>> next(g)
StopIteration

生成器表达式常与summaxmin等函数一起使用,作为函数唯一参数时,可省略两侧括号:

1
2
>>> sum(x**2 for x in range(5))
30

大师兄 wechat
欢迎关注我的微信公众号:Python大师兄