赋值魔法
5.2.1 序列解包
>>> x, y, z = 1, 2, 3
>>> x, y, z = z, x, y
# 交换多个变量的值, 称为序列解包:将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中
>>> values = 1, 2, 3
>>> values
(1, 2, 3)
>>> x, y, z = values
>>> x
1
# 在使用返回元组(或其他序列或可迭代对象的函数或方法时很有用
>>> scoundrel = {'name': 'Robin', 'girlfriend': 'Marion'}
>>> key, value = scoundrel.popitem()
>>> key
'girlfriend'
>>> value
'Marion'
# 可使用星号运算符(*)来收集多余的值,这样无需确保值和变量的个数相同
>>> a, b, *rest = [1, 2, 3, 4]
>>> rest
[3, 4]
# 还可将带星号的变量放在其他位置。
>>> name = "Albus Percival Wulfric Brian Dumbledore"
>>> first, *middle, last = name.split()
>>> middle
['Percival', 'Wulfric', 'Brian']
# 赋值语句的右边可以是任何类型的序列,但带星号的变量最终包含的总是一个列表。在变量和值的个数相同时亦如此。
>>> a, *b, c = "abc"
>>> a, b, c
('a', ['b'], 'c')
# 这种收集方式也可用于函数参数列表中(参见第6章)。
5.2.2 链式赋值
x = y = somefunction()
5.2.3 增强赋值
*= += 等,增强赋值也可用于其他数据类型
5.3 代码块:缩进
缩进的标准做法是只使用空格,且每级缩进4个空格
在很多语言中,都使用一个特殊的单词或字符(如begin或{)来标识代码块的起始位置,并使用另一个特殊的单词或字符(如end或})来标识结束位置。在Python中,使用冒号(:)指出接下来是一个代码块,并将该代码块中的每行代码都缩进相同的程度。发现缩进量与之前相同时,你就知道当前代码块到此结束了。
5.4 条件和条件语句
5.4.1 条件
- 下面的值都将被解释器视为假:
False None 0 “” () [] {}
换而言之,标准值False和None、各种类型(包括浮点数、复数等)的数值0、空序列(如空字符串、空元组和空列表)以及空映射(如空字典)都被视为假,而其他各种值都被视为真 ① ,包括特殊值True ② 。
① 至少对内置类型值来说如此。你在第9章将看到,对于自己创建的对象,解释为真还是假由你决定。
② 正如Python老手Laura Creighton指出的,这种差别类似于“有些东西”和“没有东西”的差别,而不是真和假的差别。 - 布尔值True和False属于类型bool,而bool与list、str和tuple一样,可用来转换其他的值。
注意 虽然[]和"“都为假(即bool([]) == bool(”") == False),但它们并不相等(即[] != “”)。对其他各种为假的对象来说,情况亦如此(一个更显而易见的例子是() != False)。
5.4.2 语句
str.endswith()
name = input('What is your name?')
if name.endswith('Gumby'):
print('Hello, Mr. Gumby')
else:
print('Hello, stranger')
条件表达式——C语言中三目运算符的Python版本。
下面的表达式使用if和else确定其值:
status = "friend" if name.endswith("Gumby") else "stranger"
5.4.6 更复杂的条件
表5-1 Python比较运算符
表 达 式 | 描 述 |
---|---|
x == y | x 等于y |
x < y | x小于y |
x > y | x大于y |
x >= y | x大于或等于y |
x <= y | x小于或等于y |
x != y | x不等于y |
x is y | x和y是同一个对象 |
x is not y | x和y是不同的对象 |
x in y | x是容器(如序列)y的成员 |
x not in y | x不是容器(如序列)y的成员 |
与赋值一样,Python也支持链式比较:可同时使用多个比较运算符,如0 < age < 100。
- 相等(==)而不是(=)
- 相同运算符:is
- in:成员资格运算符
- 字符串和序列的比较
字符串是依据字符的字母排列顺序进行比较的,字母都是Unicode字符,是按码点排列的,要获悉字母的顺序值,可以使用函数ord()。这个函数的作用与函数chr()相反。
>>> ord("★")
9733
>>> chr(9733)
'★'
短路逻辑和条件表达式
布尔运算符有个有趣的特征:只做必要的计算。例如,仅当x和y都为真时,表达式x and y才为真。因此如果x为假,这个表达式将立即返回假,而不关心y。实际上,如果x为假,这个表达式将返回x,否则返回y。(这将提供预期的结果,你明白了其中的原理吗?)这种行为称为短路逻辑(或者延迟求值):布尔运算符常被称为逻辑运算符,如你所见,在有些情况下将“绕过”第二个值。对于运算符or,情况亦如此。在表达式x or y中,如果x为真,就返回x,否则返回y。(你明白这样做合理的原因吗?)请注意,这意味着位于布尔运算符后面的代码(如函数调用)可能根本不会执行。像下面这样的代码就利用了这种行为:
name = input(‘Please enter your name: ‘) or ‘’
如果没有输入名字,上述or表达式的结果将为’’。在很多情况下,你都宁愿使用条件表达式,而不耍这样的短路花样。不过前面这样的语句确实有其用武之地。