《Think Python 2e》学习精粹(五):条件和递归
这章的中心话题是能够根据程序的状态执行不同命令的if语句;
1、地板除和求余
地板除运算符(floor division operator) //(求模) : 先做除法,然后将结果保留到整数;
求余运算符(modulus operator) %(求余) :将两个数相除,返回余数
>> > minutes = 105
>> > hours = minutes // 60
>> > hours
1
>> > remainder = minutes % 60
>> > remainder
45
2、布尔表达式
布尔表达式(boolean expression) :用关系运算符进行的运算;
关系运算符(relational operators) :共以下六种运算; x == y #x等于y x != y # x 不等于 y x > y # x 大于 y x < y # x 小于 y x >= y # x 大于或等于 y x <= y # x 小于或等于 y
布尔表达式(boolean expression)的运算结果要么为真( True)要么为假( False );
Python 的关系运算符 == 与 赋值运算符 = 所做的运算完全不同、运算结果也迥异;
3、逻辑运算符
逻辑运算符(logical operators) :and 、or 和 not;
and :如果两个条件都为真,整个表达式才为真;
or :如果一个或两个条件为真,那么整个表达式即为真;
not :运算符对一个布尔表达式取反;
Python 并不严格要求逻辑运算符的运算数是布尔表达式或者布尔值,任何非0的数字都被解释成为真( True );
>> > 42 and True
True
>> > not 42
False
>> >
4、有条件的执行
条件语句(Conditional statements) :检测条件、并相应地改变程序行为的语句;
有条件的执行(if 语句):如果条件为真,则缩进的语句会被执行, 如果不是,则什么也不会发生;
if x > 0 :
print ( 'x is positive' )
if 语句和函数定义有相同的结构:一个语句头跟着一个缩进的语句体;
语句体中可出现的语句数目没有限制,至少有一个,一条语句都没有的语句体可以加入 pass 语句;
5、二选一执行
二选一执行(if… else…语句):有两个可能的选择,由条件决定执行哪一个,如果条件为真,则执行第一部分语句,如果条件为假,则执行第二部分语句 ;
if x % 2 == 0 :
print ( 'x is even' )
else :
print ( 'x is odd' )
6 、链式条件
链式条件(chained conditional)(if …elif…else语句):有时有超过两个可能的情况,需要多于两个的分支,按顺序逐个检测条件,如果它们中有一个为真,相应的分支被执行,并且语句结束;
if x < y:
print ( 'x is less than y' )
elif x > y:
print ( 'x is greater than y' )
else :
print ( 'x and y are equal' )
elif 语句的数目没有限制;
else 从句并不是必须的,如果有一个 else 从句, 它必须是在最后;
即便有不止一个条件为真,也只执行第一个为真的分支;
7、嵌套条件
if x == y:
print ( 'x and y are equal' )
else :
if x < y:
print ( 'x is less than y' )
else :
print ( 'x is greater than y' )
很难快速地阅读嵌套条件(nested conditionals),尽量避免使用嵌套条件;
逻辑运算符通常是一个简化嵌套条件语句的方法;
if 0 < x:
if x < 10 :
print ( 'x is a positive single-digit number.' )
if 0 < x and x < 10 :
print ( 'x is a positive single-digit number.' )
if 0 < x < 10 :
print ( 'x is a positive single-digit number.' )
8、递归
递归(recursion) :一个函数调用它自己的过程;
def countdown ( n) :
if n <= 0 :
print ( 'Blastoff!' )
else :
print ( n)
countdown( n- 1 )
return语句:退出,与其他编程语言中的 break 语句类似;
9、递归函数的堆栈图
对于一个递归函数,在堆栈上可能同时有多个栈帧;
n=0的栈底,被称作基础情形(base case),不再进行递归调用、没有更多的栈帧;
10、无限递归
无限递归(infinite recursion) :一个递归永不会到达基础情形,永远进行递归调用, 并且程序永远不会终止;
一个具有无限递归的程序并非永远不会终止,当达到最大递归深度时,Python会报告一个错误信息;
>> > def recurse ( ) :
. . . recurse( )
. . .
>> > recurse( )
Traceback ( most recent call last) :
File "<stdin>" , line 1 , in < module>
File "<stdin>" , line 2 , in recurse
File "<stdin>" , line 2 , in recurse
File "<stdin>" , line 2 , in recurse
[ Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
遇到了无限递归,检查函数是否有基础情形,并确保基础情形没有继续调用递归;
11、键盘输入
Python 提供了内建函数 input ,可以暂停程序运行,并等待用户输入,当用户按下回车键,程序恢复执行;
input 以字符串形式返回用户键入的内容;
>> > name = input ( 'What...is your name?\n' )
What. . . is your name?
Arthur, King of the Britons!
>> > name
Arthur, King of the Britons!
提示语最后的 \n
是一个特别的字符,会造成换行;
将返回值 int 可得到整型数;
>> > prompt = 'What...is the airspeed velocity of an unladen swallow?\n'
>> > speed = input ( prompt)
What. . . is the airspeed velocity of an unladen swallow?
42
>> > speed
'42'
>> > int ( speed)
42
12、调试
当出现语法错误和运行时错误的时候,错误信息中最有用的部分是:
语法错误通常很容易被找到,但空白分隔符错误很棘手,因为空格和制表符是不可见的,而且我们习惯于忽略它们;
实际的错误可能发生在比错误信息指向的地方更早的地方,甚至在前一行,语法错误和运行时错误都是如此;
错误信息的提示不都是准确的