条件语句、断言、循环

条件和条件语句

布尔值的用武之地便是条件语句。

用作布尔表达式(如用作if语句中的条件)时,下面的值都将被解释器视为

False   None   0   ""   ()   []   {}

换而言之,标准值FalseNone、各种类型(包括浮点数、复数等)的数值0、空序列(如空字符串、空元组和空列表)以及空映射(如空字典)都被视为假,而其他各种值都被视为真,包括特殊值True

布尔值TrueFalse属于类型bool,而boolliststrtuple一样,可用来转换其他的值。

>>> bool('I think, therefore I am')
True
>>> bool(42)
True
>>> bool('')
False
>>> bool(0)
False

鉴于任何值都可用作布尔值,因此你几乎不需要显式地进行转换(Python会自动转换)。

方法endswith()功能是检测最后输入的数值

name = input('What is your name? ')
if name.endswith('Gumby'):
    print('Hello, Mr. Gumby')

如果你输入以Gumby结尾的名字,方法name.endswith将返回True,导致后续代码块执行——打印问候语。

还有一个与if语句很像的“亲戚”,它就是条件表达式——C语言中三目运算符的Python版本。下面的表达式使用ifelse确定其值:

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

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 xy是同一个对象
x is not y xy是不同的对象
x in y x是容器(如序列)y的成员
x not in y x不是容器(如序列)y的成员

 与赋值一样,Python也支持链式比较:可同时使用多个比较运算符,如0 < age < 100

有些比较运算符需要特别注意,下面就来详细介绍。

相等运算符:

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

>>> "foo" == "foo"
True
>>> "foo" == "bar"
False

一个等号是赋值运算符,用于修改值。

is:相同运算符

这个运算符很有趣,其作用看似与==一样,但实际上并非如此。

 

>>> x = y = [1, 2, 3]
>>> z = [1, 2, 3]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False

 

在前几个示例中,看不出什么问题,但最后一个示例的结果很奇怪:xz相等,但x is z的结果却为False。为何会这样呢?因为is检查两个对象是否相同(而不是相等)。变量xy指向同一个列表,而z指向另一个列表(其中包含的值以及这些值的排列顺序都与前一个列表相同)。这两个列表虽然相等,但并非同一个对象

总之,==用来检查两个对象是否相等,而is用来检查两个对象是否相同(是同一个对象)。

警告 不要将is用于数和字符串等不可变的基本值。鉴于Python在内部处理这些对象的方式,这样做的结果是不可预测的。

in:成员资格运算符

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字符,它们是按码点排列的。

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

>>> ord("a")
97
>>> ord("b")
98
>>> chr(36)
'$'

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

>>> "a" < "B"
False

一个诀窍是忽略大小写。为此可使用字符串方法lower.

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

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

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

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

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

短路逻辑和条件表达式

布尔运算符有个有趣的特征:只做必要的计算。例如,仅当xy都为真时,表达式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>'。在很多情况下,你都宁愿使用条件表达式,而不耍这样的短路花样。不过前面这样的语句确实有其用武之地。

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

 循环操作(while):

name = ''
while not name:  #没有名字为真将执行程序块
     name = input('Please enter your name: ')
print('Hello, {}!'.format(name))

 请尝试运行这些代码,并在要求你输入名字时直接按回车键。你会看到提示信息再次出现,因为name还是为空字符串,这相当于。(not假 就是真)

提示 如果你只是输入一个空格字符(将其作为你的名字),结果将如何呢?试试看。程序将接受这个名字,因为包含一个空格字符的字符串不是空的,因此不会将name视为假。这无疑是这个小程序的一个瑕疵,但很容易修复:只需将while not name改为while not name or name.isspace()while not name.strip()即可。

 for循环:

words = ['this', 'is', 'an', 'ex', 'parrot']
for word in words:
    print(word)

鉴于迭代(也就是遍历)特定范围内的数是一种常见的任务,Python提供了一个创建范围的内置函数。

>>> range(0, 10)
range(0, 10)
>>> list(range(0, 10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

范围类似于切片。它们包含起始位置(这里为0),但不包含结束位置(这里为10)。在很多情况下,你都希望范围的起始位置为0。实际上,如果只提供了一个位置,将把这个位置视为结束位置,并假定起始位置为0。

>>> range(10)
range(0, 10)

下面的程序打印数1~100:

for number in range(1,101):
    print(number)

注意,相比前面使用的while循环,这些代码要紧凑得多。

提示 只要能够使用for循环,就不要使用while循环。

posted on 2019-07-24 18:43  iBoundary  阅读(455)  评论(0编辑  收藏  举报

导航