• 沒有找到結果。

条件、循环及其他语句

5.3 代码块:缩进的乐趣

5.4.6 更复杂的条件

15 6 7 8 9 10 11 12 13 14

还有一个与if语句很像的“亲戚”,它就是条件表达式——C语言中三目运算符的Python版本。

下面的表达式使用if和else确定其值:

status = "friend" if name.endswith("Gumby") else "stranger"

如果条件(紧跟在if后面)为真,表达式的结果为提供的第一个值(这里为"friend"),否 则为第二个值(这里为"stranger")。

5.4.4 elif 子句

要检查多个条件,可使用elif。elif是else if的缩写,由一个if子句和一个else子句组合而 成,也就是包含条件的else子句。

num = int(input('Enter a number: ')) if num > 0:

print('The number is positive') elif num < 0:

print('The number is negative') else:

print('The number is zero')

5.4.5 代码块嵌套

下面穿插点额外的内容。你可将if语句放在其他if语句块中,如下所示:

name = input('What is your name? ') if name.endswith('Gumby'):

if name.startswith('Mr.'):

print('Hello, Mr. Gumby') elif name.startswith('Mrs.'):

print('Hello, Mrs. Gumby') else:

print('Hello, Gumby') else:

print('Hello, stranger')

在这里,如果名字以Gumby结尾,就同时检查名字开头,这是在第一个代码块中使用一条独 立的if语句完成的。请注意,这里还使用了elif。最后一个分支(else子句)没有指定条件——

如果没有选择其他分支,就选择最后一个分支。如果需要,这里的两个else子句都可省略。如果 省略里面的else子句,将忽略并非以Mr.或Mrs.打头的名字(假设名字为Gumby)。如果省略外面 的else子句,将忽略陌生人。

5.4.6 更复杂的条件

这就是你需要知道的有关if语句的全部知识。下面来说说条件本身,因为它们是有条件执行 中最有趣的部分。

1. 比较运算符

在条件表达式中,最基本的运算符可能是比较运算符,它们用于执行比较。表5-1对比较运 算符做了总结。

表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的成员

对不兼容的类型进行比较

从理论上说,可使用<和<=等运算符比较任意两个对象x和y的相对大小,并获得一个真 值,但这种比较仅在x和y的类型相同或相近时(如两个整数或一个整数和一个浮点数)才有 意义。

将整数与字符串相加毫无意义,检查一个整数是否小于一个字符串也是一样。奇怪的 是,在Python 3之前,竟然可以这样做。不过即便你使用的是较旧的Python版本,也应对这类 比较敬而远之,因为结果是不确定的,每次执行程序时都可能不同。在Python 3中,已经不允 许这样比较不兼容的类型了。

与赋值一样,Python也支持链式比较:可同时使用多个比较运算符,如0 < age < 100。 有些比较运算符需要特别注意,下面就来详细介绍。

相等运算符

要确定两个对象是否相等,可使用比较运算符,用两个等号(==)表示。

>>> "foo" == "foo"

True

>>> "foo" == "bar"

False

两个等号?为何不像数学中那样使用一个等号呢?相信你很聪明,自己就能够明白其中的原 因,但这里还是试试一个等号吧。

>>> "foo" = "foo"

SyntaxError: can't assign to literal

1

>>> y.reverse()

在这个示例中,我首先创建了两个不同的列表x和y。如你所见,x is not y(与x is y相反)

name = input('What is your name?') if 's' in name:

print('Your name contains the letter "s".') else:

print('Your name does not contain the letter "s".')

字符串和序列的比较

字符串是根据字符的字母排列顺序进行比较的。

>>> "alpha" < "beta"

True

虽然基于的是字母排列顺序,但字母都是Unicode字符,它们是按码点排列的。

>>> " " < " "

True

实际上,字符是根据顺序值排列的。要获悉字母的顺序值,可使用函数ord。这个函数的作 用与函数chr相反:

>>> ord(" ") 128585

>>> ord(" ") 128586

>>> chr(128584) ' '

这种方法既合理又一致,但可能与你排序的方式相反。例如,涉及大写字母时,排列顺序就 可能与你想要的不同。

>>> "a" < "B"

False

一个诀窍是忽略大小写。为此可使用字符串方法lower,如下所示(参见第3章):

>>> "a".lower() < "B".lower() True

>>> 'FnOrD'.lower() == 'Fnord'.lower() True

其他序列的比较方式与此相同,但这些序列包含的元素可能不是字符,而是其他类型的值。

>>> [1, 2] < [2, 1]

True

如果序列的元素为其他序列,将根据同样的规则对这些元素进行比较。

>>> [2, [1, 4]] < [2, [1, 5]]

True

2. 布尔运算符

至此,你已见过很多返回真值的表达式(实际上,考虑到所有值都可解释为真值,因此所有 的表达式都返回真值),但你可能需要检查多个条件。例如,假设你要编写一个程序,让它读取 一个数,并检查这个数是否位于1~10(含)。为此,可像下面这样做:

number = int(input('Enter a number between 1 and 10: ')) if number <= 10:

1 2 3 4 5

15 6 7 8 9 10 11 12 13 14

if number >= 1:

print('Great!') else:

print('Wrong!') else:

print('Wrong!')

这可行,但有点笨拙,因为你输入了print('Wrong!')两次。重复劳动可不是好事,那么该如 何办呢?很简单。

number = int(input('Enter a number between 1 and 10: ')) if number <= 10 and number >= 1:

print('Great!') else:

print('Wrong!')

注意 通过使用链式比较1 <= number <= 10可进一步简化这个示例。也许原本就应该这样做。

运算符and是一个布尔运算符。它接受两个真值,并在这两个值都为真时返回真,否则返回 假。还有另外两个布尔运算符:or和not。通过使用这三个运算符,能以任何方式组合真值。

if ((cash > price) or customer_has_good_credit) and not out_of_stock:

give_goods()

短路逻辑和条件表达式

布尔运算符有个有趣的特征:只做必要的计算。例如,仅当x和y都为真时,表达式x and y才为真。因此如果x为假,这个表达式将立即返回假,而不关心y。实际上,如果x为假,这 个表达式将返回x,否则返回y。(这将提供预期的结果,你明白了其中的原理吗?)这种行为 称为短路逻辑(或者延迟求值):布尔运算符常被称为逻辑运算符,如你所见,在有些情况下 将“绕过”第二个值。对于运算符or,情况亦如此。在表达式x or y中,如果x为真,就返回 x,否则返回y。(你明白这样做合理的原因吗?)请注意,这意味着位于布尔运算符后面的代 码(如函数调用)可能根本不会执行。像下面这样的代码就利用了这种行为:

name = input('Please enter your name: ') or '<unknown>'

如果没有输入名字,上述or表达式的结果将为'<unknown>'。在很多情况下,你都宁愿使 用条件表达式,而不耍这样的短路花样。不过前面这样的语句确实有其用武之地。

5.4.7 断言

if语句有一个很有用的“亲戚”,其工作原理类似于下面的伪代码:

if not condition:

crash program

问题是,为何要编写类似于这样的代码呢?因为让程序在错误条件出现时立即崩溃胜过以后

再崩溃。基本上,你可要求某些条件得到满足(如核实函数参数满足要求或为初始测试和调试提 供帮助),为此可在语句中使用关键字assert。

>>> age = 10

>>> assert 0 < age < 100

>>> age = -1

>>> assert 0 < age < 100

Traceback (most recent call last):

File "<stdin>", line 1, in ? AssertionError

如果知道必须满足特定条件,程序才能正确地运行,可在程序中添加assert语句充当检查点,

这很有帮助。

还可在条件后面添加一个字符串,对断言做出说明。

>>> age = -1

>>> assert 0 < age < 100, 'The age must be realistic' Traceback (most recent call last):

File "<stdin>", line 1, in ?

AssertionError: The age must be realistic

5.5 循环

至此,你知道了如何在条件为真(或假)时执行操作,但如何重复操作多次呢?例如,你可 能想创建一个程序,每月都提醒支付房租。如果只使用已介绍过的工具,必须像下面这样编写这 个程序(伪代码):

send mail

wait one month send mail wait one month send mail wait one month

(... and so on)

但是如果希望程序这样不断执行下去,直到人为停止,该如何办呢?基本上,你需要编写类 似于下面的代码(也是伪代码):

while we aren't stopped:

send mail wait one month

再来看一个更简单的例子,假设要打印1~100的所有数。同样,你可采用笨办法。

print(1) print(2) print(3) ...

print(99) print(100)

但如果你愿意使用笨办法,就不会求助于Python了,不是吗?

1

2

3

4