Python 选择与循环
本文章总结了董付国老师的Pthon程序设计(第2版)书的内容,仅供个人学习使用,如有侵权,立刻删除 by:mfdy
文章链接:mfdy’s blog: Python选择与循环
CSDN目录:https://blog.csdn.net/mofadiyu/article/details/90178542
3.1 条件表达式
首先,说一下所有的运算符:
- 算术运算符:
+
、-
、*
、/
、//
、%
、**
- 关系运算符:
>
、<
、==
、<=
、>=
、!=
,可以连续使用,如
>>> 1 < 2 < 3
True
>>> 1 < 2 > 3
False
>>> 1 < 3 > 2
True
- 测试运算符:
in
、not in
、is
、is not
- 逻辑运算符:
and
、or
、not
,注意短路求值 - 位运算符:
~
、&
、|
、^
、<<
、>>
- 矩阵乘法运算符:
@
在选择和循环结构中,条件表达式的值只要不是False、0(或0.0、0j等)、空值None、空列表、空元组、空集合、空字典、空字符串、空range对象或其他空迭代对象,Python解释器均认为与True等价。
从这个意义上来讲,几乎所有的Python合法表达式都可以作为条件表达式,包括含有函数调用的表达式。
例如:
if 3:
a = [1, 2, 3]
if a:
都是可执行的
其中需要注意的是,逻辑运算符and
和or
具有惰性求值的特点,即不管后面的正不正确,先执行前面的判断
3.2 选择结构
3.2.1 单分支选择结构
if 表达式:
语句块
当表达式值为True或者其他等价值时,表示条件满足,语句块将被执行,否则不执行
x = input('Input two numbers:')
# split()返回分割后的字符串列表
a, b = map(int, x.split())
if a > b:
# 序列解包,交换两个变量的值
a, b = b, a
print(a, b)
关于split():
str.split(str="", num=string.count(str))
参数
- str – 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
- num – 分割次数。默认为 -1, 即分隔所有。
str = "asdfg \nsarwar \nfegtsgr"
# 以空格为分隔符,包含\n
>>> print(str.split( ))
['asdfg', 'sarwar', 'fegtsgr']
# 以空格为分隔符,分割成两个
>>> print(str.split(' ', 1))
[['asdfg', 'sarwar \nfegtsgr']]
3.2.2 双分支选择结构
if 表达式:
语句块1
else:
语句块2
比如:
if a > b:
print(a)
else:
print(b)
Python还支持如下形式的表达式:
value1 if condition else value2
即condition的值与True等价时,值为value1,否则值为value2。
在value1和value2中可以使用复杂表达式,包括函数调用和基本输出语句。
并且该表达式具有惰性求值的特点。
print(6) if a > 3 else print(5)
print(6 if a > 3 else 5)
import math
import random
x = math.sqrt(9) if 2 > 3 else random.randint(1, 100)
>>> x
77
3.2.3 多结构分支
if 表达式1:
语句块1
elif 表达式2:
语句块2
elif 表达式3:
语句块3
……
else:
语句块4
其中,关键字elif
是else if
的缩写
3.2.4 选择结构的嵌套
选择结构可以嵌套,比如:
if 表达式1:
语句块1
if 表达式2:
语句块2
……
3.2.5 例子
- 面试资格确认
age = 24
subject = "计算机"
college = "非重点"
if (age > 25 and subject == "电子信息工程") or (college == "重点" and subject == "电子信息工程" ) or (age <= 28 and subject == "计算机"):
print("恭喜,你已获得我公司的面试机会!")
else:
print("抱歉,你未达到面试要求")
- 编写程序,判断某天是某年第几天
import time
date = time.localtime()
year, month, day = date[:3]
day_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):
day_month[1] = 29
if month == 1:
print(day)
else:
print(sum(day_month[:month - 1]) + day)
其中,判断闰年可以直接使用calendar模块的方法:
>>> caledar.isleap(2016)
True
或者使用下面的方法直接计算今天是今年的第几天:
>>> datetime.date.today().timetuple().tm_yday
208
>>> datetime.date(2015, 7, 25).timetuple().tm_yday
206
也可以使用datetime模块提供的功能来计算
import datetime
today = datetime.date.today()
>>> today
datetime.date(2019, 4, 3)
firstDay = datetime.date(today.year, 1, 1)
>>> firstDay
datetime.date(2019, 1, 1)
daysDelta = today - firstDay + datetime.timedelta(days = 1)
>>> daysDelta.days
208
3.3 循环结构
3.3.1 for循环和while循环
Python提供了两种基本的循环结构语句——while语句、for语句。
while循环一般用于循环次数难以提前确定的情况,也可以用于循环次数确定的情况。
for循环一般用于循环次数可以提前确定的情况,尤其是用于枚举序列或迭代对象中的元素。
一般优先考虑使用for循环。
相同或不同的循环结构之间都可以互相嵌套,实现更为复杂的逻辑。
while 条件表达式:
循环体
[else: #循环结束,且不是因break结束,执行else部分
else子句代码块]
for 取值 in 序列或迭代对象:
循环体
[else:
else子句代码块]
3.3.2 循环结构的优化
为了优化程序以获得更高的效率和运行速度,在编写循环语句时,应尽量减少循环内部不必要的计算,将与循环变量无关的代码尽可能地提取到循环之外。对于使用多重循环嵌套的情况,应尽量减少内层循环中不必要的计算,尽可能地向外提。
例如:
优化前的代码:
digits = (1, 2, 3, 4)
for i in range(1000):
result = []
for i in digits:
for j in digits:
for k in digits:
result.append(i * 100 + j * 10 + k)
print(result)
优化后的代码:
digits = (1, 2, 3, 4)
for i in range(1000):
result = []
for i in digits:
i = i * 100
for j in digits:
j = j * 10
for k in digits:
result.append(i + j + k)
print(result)
3.4 break 和 continue 语句
break语句在while循环和for循环中都可以使用,一般放在if选择结构中,一旦break语句被执行,将使得整个循环提前结束。
continue语句的作用是终止当前循环,并忽略continue之后的语句,然后回到循环的顶端,提前进入下一次循环。
除非break语句让代码更简单或更清晰,否则不要轻易使用。
例:计算小于100的最大素数
for n in range(100, 1, -1):
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
break
else:
print(n)
break
当删除最后一个break时,则为输出1-100的所有素数
警惕continue可能带来的问题:
i = 0
while i < 10:
if i % 2 == 0:
continue
print(i)
i += 1
永不结束的死循环,Ctrl+C强行终止。
这样子就不会有问题
for i in range(10):
if i % 2 == 0:
continue
print(i, end = ' ')
3.5 案例精选
例1:计算1 + 2 + … + 100 的值
s = 0
for i in range(1, 101):
s += i
print(s)
例2:输出序列中的元素
a_list = ['a', 'b', 'mpilgrim', 'z', 'example']
for i, v in enumerate(a_list):
print('列表的第', i + 1, '个元素是:', v)
例3:输出“水仙花数”。所谓水仙花数是指1个3位的十进制数,其各位数字的立方和等于该数本身。例如:153是水仙花数,因为153 = 13 + 53 + 33 。
for i in range(100, 1000):
#这里是序列解包的用法
bai, shi, ge = map(int, str(i))
if ge**3 + shi**3 + bai**3 == i:
print(i)
例4:打印九九乘法表。
for i in range(1,10):
for j in range(1,i + 1):
print('{0}*{1}={2}'.format(i, j, i * j).ljust(6), end = ' ')
print()
例5:编写程序,生成一个含有20个随机数的列表,要求所有元素不相同,并且每个元素的值介于1到100之间。
import random
x = []
while True:
if len(x)==20:
break
n = random.randint(1, 100)
if n not in x:
x.append(n)
print(x)
print(len(x))
print(sorted(x))
如果用集合来做,会更简单一些
from random import randint
x = set()
while len(x) < 20:
x.add(randint(1, 100))
print(x)
print(sorted(x))
例6: 递归算法求解汉诺塔问题
def hannoi(num, src, dst, temp=None):
global times #声明用来记录移动次数的变量为全局变量
assert type(num) == int, 'num must be integer' #确认参数类型和范围
assert num > 0, 'num must > 0'
if num == 1: #只剩最后或只有一个盘子需要移动,这也是函数递归调用的结束条件
print('The {0} Times move:{1}==>{2}'.format(times, src, dst))
times += 1
else:
#递归调用函数自身,先把除最后一个盘子之外的所有盘子移动到临时柱子上
hannoi(num-1, src, temp, dst)
hannoi(1, src, dst) #把最后一个盘子直接移动到目标柱子上
#把除最后一个盘子之外的其他盘子从临时柱子上移动到目标柱子上
hannoi(num-1, temp, dst, src)
times = 1 #用来记录移动次数的变量
hannoi(3, 'A', 'C', 'B') #A表示最初放置盘子的柱子,C是目标柱子,B是临时柱子
ljust() 方法返回一个原字符串左对齐,并使用空格填充至指定长度的新字符串。如果指定的长度小于原字符串的长度则返回原字符串。
end