第三章:选择与循环
3.1条件表达式
3.1.1算术运算符
:+、-、*、/、//、%、**
3.1.2关系运算符
:>、<、==、<=、>=、!=,可以连续使用,如
>>>1<2<3
True
>>>1<2>3
False
>>>1<3>2
True
3.1.3测试运算符
:(成员测试运算符:)in、not in、(统同一性测试运算符:)is、is not
3.1.4逻辑运算符
:and、or、not,注意短路求值
3.1.5位运算符
:~、&(与)、|(或)、^(异或)、<<、>>
3.1.6矩阵乘法运算符
:@
在选择和循环结构中,条件表达式的值只要不是False、0(或0.0、0j等)、空值None、空列表、空元组、空集合、空字典、空字符串、空range对象或其他空迭代对象,python解释器均认为与True等价。
从这个意义上来讲,几乎所有的python合法表达式都可以作为条件表达式,包括含有函数调用的表达式。
>>>if 3: #使用整数作为条件表达式
print(5)
5>>>a=[1,2,3] #使用列表作为条件表达式
>>>if a:
print(a)
[1, 2, 3]>>>a=[] #空列表等价于False,这个条件不成立
>>>if a:
print(a)
else:
print('empty')
empty
>>>i=s=0
>>>while i<=10: #使用关系表达式作为条件表达式
s+=i
i+=1
>>>print(s)
55>>>i=s=0
>>>while True: #使用常量True作为条件表达式(死循环)
s+=i
i+=1
if i>10:
break
>>>print(s)
55>>>s=0
>>>for i in range(0,11,1): #使用迭代对象中的所以元素(遍历对象中的每个元素,左闭右开)
s+=i
>>>print(s)
55
逻辑运算符and和or以及关系运算符具有惰性求值特点
关系运算也具有短路求值或惰性求值的特点,只计算必须计算的表达式的值。
以“and”为例,对于表达式“表达式1 and 表达式2”而言,如果“表达式1”的值为False或其他等价值时,不论“表达式2”的值是什么,这更个表达式的值都是“False”,此时“表达式2”的值无论是什么都不影响整个表达式的值,因此将不会被计算,从而减少不必要的计算和判断。
在设计条件表达式时,如果能够大概预测不同条件失败的概率,并将多个条件根据”and“和”or“运算的短路求值特性进行组织,可以大幅度提高程序运行效率。下面的函数用来使用用户指定的分隔符将多个字符串连接成一个字符串,如果用户没有指定分隔符则使用逗号。
and:把特别容易失败的条件放到前面
>>>def Join(chList,sep=None):
#定义了一个函数,给了一个列表,参数(带默认值)
return (sep or ',').join(chList) #返回,使用sep或者,作为分隔将列表分隔>>>chTest=['1','2','3','4','5']
>>>Join(chTest) #没有指定分隔符,代表False,就会执行定义函数返回的return的值
'1,2,3,4,5'>>>Join(chTest,':') #指定:作为分隔符
'1:2:3:4:5'>>>Join(chTest,' ') #指定空格作为分隔符
'1 2 3 4 5'
在python中,条件表达式中不允许使用赋值运算符”=“,避免了其他语言中误将关系运算符”==“写作赋值运算符”=“带来的麻烦,例如下面的代码,在条件表达式中使用赋值运算符”=“将抛出异常,提示语法错误。
>>>if a=3:
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?>>>if (a=3) and (b=4):
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
3.2选择结构
3.2.1单分支选择结构
if
if 表达式:
语句块
x=input('Input two number:') #输入两个数字
a,b=map(int,x.split())
#用空格把两个数字分隔开,变成两个字符串,再用map变成int
if a>b: #如果a大于b,交换两个数字
a,b=b,a #序列解包,交换两个变量的值
print(a,b)
3.2.2双分支结构
if...else..
if 表达式:
语句块1
else:
语句块2
>>>chTest=['1','2','3','4','5']
>>>if chTest: #不是空列表都是True
print(chTest)
else:
print('Empty')
['1', '2', '3', '4', '5']
python还支持如下形式的表达式:
value1 if condition else value2
当条件表达式condition的值与True等价时,表达式的值为value1,否则表达式的值为value2.另外,在value1和value2中还可以使用复杂表达式,包括函数调用和基本输出语句。这个结构的表达式也具有惰性求值的特点(不需要执行的就不执行)。
>>>a=5
>>>print(6) if a>3 else print(5)
6>>>print(6 if a>3 else 5)
6>>>b=6 if a>13 else 9
>>>b
9
#此时还没有导入math模块
>>>x=math.sqrt(9) if 5>3 else randint(1,100) #1-100之间的随机数
Traceback (most recent call last):
File "<pyshell#57>", line 1, in <module>
x=math.sqrt(9) if 5>3 else randint(1,100)
NameError: name 'math' is not defined
>>>import math#此时还没导入random模块,但是由于条件表达式5>3的值为True,所以正常运行
>>>x=math.sqrt(9) if 5>3 else random.randint(1,100)#此时还没有导入random模块,由于条件表达式2>3的值为False,需要第二个表达式的值,因此出错
>>>x=math.sqrt(9) if 2>3 else random.randint(1,100)
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
x=math.sqrt(9) if 2>3 else random.randint(1,100)
NameError: name 'random' is not defined>>>import random
>>>x=math.sqrt(9) if 2>3 else random.randint(1,100)
3.2.3多分支结构
if...elif(...elif)...else
if 表达式1:
语句块1
elif 表达式2:
语句块2
elif 表达式3:
语句块3
else:
语句块4
其中,关键字elif是else if的缩写。
利用多分支选择结构将成绩从百分制转变到等级制
def func(score):
if score>100:
return 'wrong score.must<=100'
elif score>=90:
return 'A'
elif score>=80:
return 'B'
elif score>=70:
return 'C'
elif score>=60:
return 'D'
elif score>=0:
return 'E'
else:
return 'wrong score.must>0'
3.2.4选择结构的嵌套
if...if(...)...else...if
if 表达式1:
语句块1
if 表达式2:
语句块2
else:
语句块3
else:
if 表达式4:
语句块4
注意:缩进必须要正确并且一致
使用嵌套的选择结构实现百分制成绩到等级制的转换
>>>def func(score):
degree='DCBAAE' #两个A级,90及以上和100分
if score>100 or score<0: #分数非法
return 'wrong score.must between 0 and 100'
else:
index=(score - 60)//10 #让这个分数-60再整除10
if index>=0:
return degree[index]
else:
return degree[-1]
3.2.5构建跳转表实现多分支选择结构
使用列表、元组或字典可以很容易构建跳转表,在某些场合下可以更快速地实现类似于多分支选择结构的功能。
构建跳转表
#构建一个字典,值对应的是一个lambda表达式(相当于一个函数)
funcDict={'1':lambda:print('You input 1'),
'2':lambda:print('You input 2'),
'3':lambda:print('You input 3')}
x=input('Input an integer to call different function:')
func=funcDict.get(x,None)
#如果x的值在字典中,返回字典对应的值;否则,返回None
if func: #如果返回一个函数,就调用函数
func()
else:
print('Wrong integer')
3.2.6选择结构应用
例3-1
:面试资格确认
优先级:and>or
换行:\(续航符),外面再加一对括号
and和or的短路特性,看条件放的位置
#面试资格确认
age=24
subject="计算机"
college="非重点"
if (age>25 and subject=="电子信息工程") or \
(college=="重点" and subject=="电子信息工程") or\
(age<=28 and subject=="计算机"):
print("恭喜,你已获得我公司的面试机会!")
else:
print("抱歉,你未达到面试要求")
例3-2
:用户输入若干个分数,求所有分数的平均分。每输入一个分数后询问是否继续输入下一个分数,回答“yes”就继续输入下一个分数,回答“no”就停止输入分数。
#若干分数平均分
numbers=[] #使用列表存放临时数据
while True: #写一个循环,让用户不停的输入数字
x=input('请输入一个成绩:') #input让用户输入内容,返回的是字符串类型
try: #异常处理结构
#使用float将字符串转换为实数,并添加至列表中
numbers.append(float(x))
except:
print("不是合法成绩") #不管输入的成绩有效还是无效都会继续
while True:
#限定用户输入内容必须为yes或no
flag=input('继续输入吗?(yes/no)')
#.lower():将用户输入的字符转换为小写
if flag.lower() not in ('yes','no'):
print('只能输入yes或no')
else:
break
if flag.lower()=='no':
break
print(sum(numbers)/len(numbers))
例3-3
:编写程序,判断今天是今年的第几天。
#判断今天是今年的第几天
import time
#获取当前日期时间
date=time.localtime()
#返回的前三项是年、月、日,类型是元组
year,month,day=date[:3]
#最好使用列表,后面要修改;1-12月的天数
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): #判断是否为闰年
#闰年二月份有29天,将上面day_month的第一个位置的数字换掉
day_month[1]=29
if month==1:
print(day)
else:
print(sum(day_month[:month-1])+day)
其中闰年判断可以直接使用calendar模块的方法
>>>import calendar
>>>calendar.isleap(2024) #.isleap:判断一个年份是否为闰年
True
>>>calendar.isleap(2015)
False
直接计算今天是今年的第几天
>>>import datetime #标准库datetime,这个模块中有一个类date,date有一个方法today(),可以返回今天的日期时间;.timetuple():转换为元组,其中.tm_yday,表示今天是今年的第几天
>>>datetime.date.today().timetuple().tm_yday
33#date是一个类,可以当作函数使用,有构造方法
>>>datetime.date(2015,7,25).timetuple().tm_yday #2015.7.25是那年的第几天
206
也可以使用datetime模块提供的功能来计算
>>>import datetime
>>>today=datetime.date.today() #获取今天的日期
>>>today
datetime.date(2024, 2, 2)
>>>firstDay=datetime.date(today.year,1,1) #今年的一月一日
>>>firstDay
datetime.date(2024, 1, 1)
>>>daysDelta=today-firstDay+datetime.timedelta(days=1) #日期和数字不能相加,.timedelta进转换
>>>daysDelta.days #今天是今年的第几天
33
datetime还提供了其他功能
>>>now=datetime.datetime.now() #获取当前日期时间
>>>now
datetime.datetime(2024, 2, 2, 21, 56, 43, 767786) #年月日时分秒
>>>now.replace(second=30) #替换日期时间中的秒
datetime.datetime(2024, 2, 2, 21, 56, 30, 767786)
>>>now+datetime.timedelta(days=5) #计算5天后的日期时间
datetime.datetime(2024, 2, 7, 21, 56, 43, 767786)
>>>now+datetime.timedelta(weeks=-5) #计算5周前的日期时间(负数往前的)
datetime.datetime(2023, 12, 29, 21, 56, 43, 767786)
计算两个日期之间相差多少天
#计算两个日期之间相差多少天
def daysBetween(year1,month1,day1,
year2,month2,day2):
from datetime import date
dif=date(year1,month1,day1)
dif=dif-date(year2,month2,day2) #两个相减得到timedelta对象
return dif.days
#timedelta对象中有一个days成员是计算两个日期之间相差多少天
print(daysBetween(2024,2,2,2024,1,2))
print(daysBetween(2024,2,2,2016,1,2))
3.3循环
3.3.1for循环与while循环
python提供了两种基本的循环结构语句——while语句、for语句。
while循环一般用于循环次数难以提前确定的情况,也可以用于循环次数确定的情况。
foru循环一般用于循环次数可以提前确定的情况,尤其是用于枚举序列或迭代对象中的元素。
一般优先考虑使用for循环。
相同或不同的循环结构之间都可以互相嵌套,实现更为复杂的逻辑。
while 条件表达式:
循环体
[else:
else字句代码块] #上面的语句执行顺利就会执行else语句
for 取值 in 序列(列表,元组,集合,字典,字符串)或迭代对象(range):
循环体
[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)
优化后的代码:
>>>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)
另外,在循环中应尽量引用局部变量,因为局部变量的查询和访问速度比全局变量略快,在使用,模块中的方法时,可以通过将其转换为局部变量来提高运行速度。
import time
import math
start=time.time() #获取当前时间
for i in range(10000000):
math.sin(i) #求正弦值
print('Time Used:',time.time()-start) #输出所有时间
loc_sin=math.sin #赋值给loc_sin
start=time.time()
for i in range(100000000):
loc_sin(i) #调用loc_sin求正弦值
print('Time Used:',time.time()-start)
3.4break和continue语句
break语句在while循环和for循环中都可以使用,一般放在if选择结构中,一旦break语句被执行,将使得整个循环提前结束。
continue语句的作用是终止当前循环(结束本次循环),并忽略continue之后的语句,然后回到循环的顶端,提前进入下一次循环。
除非break语句让代码更简单或更清晰,否则不要轻易shi'yon
>>>for n in range(100,1,-1): #100-2,从大往小
for i in range(2,n):
if n%i==0: #能整除
break #执行break,就不会执行下面的else
else: #此else与上面的for是对齐的,不是第一个for,是因为>>>的关系看起来在一个缩进
print(n)
break #结束最外层的循环
97
删除上面代码中最后一个break语句,则可以用来输出100以内的所有素数。
>for n in range(100,1,-1):
for i in range(2,n):
if n%i==0:
break
else:
print(n,end=' ')
97 89 83 79 73 71 67 61 59 53 47 43 41 37 31 29 23 19 17 13 11 7 5 3 2
警惕continue可能带来的问题:
>i=0
>while i<10:
if i%2==0:
continue #后面的代码不执行了,直接进入下次循环
print(i)
i+=1 #被continue绕过
KeyboardInterrupt
这样子就不会有问题
>for i in range(10):
if i%2==0:
continue
print(i,end=' ')
1 3 5 7 9
>for i in range(10):
if i%2==0:
i+=1 #写了也没啥用
continue
print(i,end=' ')
1 3 5 7 9
每次进入循环时的i已经不是上次的i,所以修改其值并不会影响循环的执行,
>for i in range(7):
print(id(i),':',i)
2245439783120 : 0
2245439783152 : 1
2245439783184 : 2
2245439783216 : 3
2245439783248 : 4
2245439783280 : 5
2245439783312 : 6
3.5案例精选
例3-4
:计算1+2+3+……+100的值。
#计算1+2+3+……+100的值
s=0
for i in range(1,101): #左闭右开
s=s+i
print('1+2+3+...+100=',s)
#sum可以对序列和可迭代对象进行求和
print('1+2+3+...+100=',sum(range(1,101)))
例3-5
:输出序列中的元素
#输出序列中的元素
a_list=['a','b','mpilgrim','z','example']
#使用enumerate,返回的对象是元组,其中包含(索引,值)
for i,v in enumerate(a_list):
print('列表的第',i+1,'个元素是:',v)
例3-6
:求1-100之间能被7整除但不能被5整除的所有整数
#求1-100之间能被7整除但不能被5整除的所有整数
for i in range(1,101):
if i%7==0 and i%5!=0:
print(i)
例3-7
:输出”水仙花数“。所谓水仙花数是指1个3位的十进制数,其各位数字的立方和等于该数本身。例如:153是水仙花数,因为153=1的3次方+5的3次方+3的3次方。
#水仙花数
#获取所有的三位数
for i in range(100,1000):
#获得每位上的数字,先转换为字符串变成序列
#再使用map把int映射到序列中去,也就是把字符串中的三个字符都转化为数字
bai,shi,ge=map(int,str(i))
if ge**3+shi**3+bai**3==i:
print(i)
例3-8
:求平均分
#求平均分
score=[70,90,78,85,97,94,65,80]
s=0
for i in score:
s+=i
print(s/len(score))
print(sum(score)/len(score))
例3-9
:打印九九乘法表
#打印九九乘法表
for i in range(1,10):
for j in range(1,i+1):
#ljust左对齐6位
print('{0}*{1}={2}'.format(i,j,i*j).ljust(6),end=' ')
print()
例3-10
:求200以内能被17整除的最大正整数。
#求200以内能被17整除的最大正整数
for i in range(200,0,-1):
if i%17==0:
print(i)
break
例3-11
:判断一个数是否为素数
#判断一个数是否为素数
import math
n=input('Input an inter:')
n=int(n)
#math.sqrt(n)求平方根;math.ceil向上取整
m=math.ceil(math.sqrt(n)+1)
for i in range(2,m):
if n%i==0 and i<n:
print('No')
break
else:
print('Yes')
例3-12
:鸡兔同笼问题。假设共有鸡、兔30只,脚90只,求鸡、兔各有多少只。
#鸡兔同笼问题。假设共有鸡、兔30只,脚90只,求鸡、兔各有多少只。
for ji in range(0,31):
if 2*ji+(30-ji)*4==90:
#鸡兔同笼另一种算法
def demo(tui,jitu):
#让鸡的腿全部抬起,只剩兔子的腿,除二就是兔子的数量
tu=(tui-jitu*2)/2
if int(tu)==tu: #判断得出的数是否为整数
return (int(tu),int(jitu-tu))
else:
return 'Data Error'
print(demo(90,30))
例3-13
:输出由1、2、3、4这四个数字组成的每位数都不相同的所有三位数。
#输出由1、2、3、4这四个数字组成的每位数都不相同的所有三位数。
digits=(1,2,3,4) #定义元组
for i in digits:
for j in digits:
for k in digits:
if i!=j and j!=k and i!=k:
print(i*100+j*10+k,end=' ')
从代码优化的角度来讲,上面这段代码并不是很好,其中有些判断完全可以在外层循环来做,从而提高运行效率。
digits=(1,2,3,4)
for i in digits:
for j in digits:
if i==j:
continue
for k in digits:
if k==i or k==j:
continue
print(i*100+j*10+k,end=' ')
进一步优化
def demo1(data,k=3):
assert k==3,'k must be 3'
for i in data:
if i==0:continue #数字第一位不能是0
ii=i*100
for j in data:
if j==i:
continue
jj=j*10
for k in data:
if k!=i and k!=j:
print(ii+jj+k,end=' ')
data=(1,2,3,4)
demo1(data)
使用集合实现同样的功能
#使用集合实现同样的供能
def demo2(data,k=3):
data=set(data) #将data转换为集合
for i in data:
if i==0:continue
ii=i*100
for j in data-{i}:#集合之间的相减
jj=j*10
for k in data-{i,j}:
print(ii+jj+k)
例3-14
:生成一个含有20个随机数的列表,要求所有元素不相同,并且每个元素的指介于1到100之间。
#生成一个含有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))
>import random
>random.sample(range(1,101),20) #.sample从range序列中选择不重复的320个数
[36, 55, 32, 19, 70, 87, 51, 48, 91, 9, 54, 92, 95, 40, 86, 6, 71, 56, 4, 63]>random.sample(range(1,10),20)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
random.sample(range(1,10),20)
File "D:\lib\random.py", line 482, in sample
raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative
例3-15
:计算组合数C(n,i),即从n个元素中任选i个,有多少种选法。
根据组合数定义,需要计算3个数的阶乘,在很多编程语言中都很难直接使用整型变量表示大数的阶乘结果,虽然Python并不存在这个问题,但是计算大数的阶乘仍需要相当多的时间。本例提供另一种计算方法:以Cni(8,3)为例,按定义式展开为Cni(8,3)=8!/3/(8-3) !=(8*7*6*5*4*3*2*1)/(3*2*1)/(5*4*3*2*1),对于(5,8]区间的数,分子上出现一次而分母上没出现;(3,5]区间的数在分子、分母上各出现一次;[1,3]区间的数分子上出现一次而分母上出现两次。
#计算组合数C(n,i),即从n个元素中任选i个,有多少种选法。
def Cnil(n,i):
#保证n和i都是整数,并且n大于等于i
if not (isinstance(n,int) and isinstance(i,int) and n>=i):
print('n and i must be intrgers and n must be lager than or equal to i')
return
result=1
Min,Max=sorted((i,n-i))
for i in range(n,0,-1):
if i>Max:
result*=i
elif i<Min:
result/=i
return result
也可以使用math库中的阶乘函数直接按组合数定义实现。
>def Cni2(n,i):
import math#算出n的阶乘,i的阶乘,n-i的阶乘,分别相除
return int(math.factorial(n)/math.factorial(i)/math.factorial(n-i))>Cni2(6,2)
15
还可以直接使用python标准库itertools提供的函数。
>import itertools #标准库itertools
#.combinations从60个元素里面任意选2(i)个,有多少种选法
#转换成元组后求长度
>len(tuple(itertools.combinations(range(60),2)))
1770#不建议这样写,占用的空间非常大
itertools还提供了排列函数permutatuons()。其返回值是具有惰性求值的对象
>import itertools
#从1-3中任选两个,其排列分别是什么;for循环遍历输出
>for item in itertools.permutations(range(1,4),2):
print(item)
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)
itertools还提供了用于循环遍历可迭代对象元素的函数cycle()。
>import itertools
>x='Private Key'
>y=itertools.cycle(x) #创建一个cycle对象,是可迭代的;循环遍历序列中的元素
>for i in range(20):
print(next(y),end=',') #可以使用next从迭代对象里面获取一个元素,每次获取一个元素,将其输出不换行
P,r,i,v,a,t,e, ,K,e,y,P,r,i,v,a,t,e, ,K, #首尾相接输出>for i in range(5):
print(next(y),end=',')
e,y,P,r,i, #接着上面输出过的输出#加密时会用到
itertools还提供了根据一个序列的值对另一个序列进行过滤的函数compress()。
>x=range(1,20)
>y=(1,0)*9+(1,) #19个元素
>y
(1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)>list(itertools.compress(x,y)) #根据y的值,对x进行过滤
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19] #y中是1等价于True,0等价于False
itertools还提供了根据函数返回值对序列进行分组的函数groupby()。
>def group(v): #定义函数,接收参数v
if v>10:
return 'greater than 10'
elif v<5:
return 'less than 5'
else:
return 'between 5 and 10'
>x=range(20)#对x进行分组,依据group函数
>y=itertools.groupby(x,group) #根据函数返回值对序列元素进行分组;得到的y是一个字典
>for k,v in y: #遍历字典中的键值
print(k,':',list(v)) #输出键和值
less than 5 : [0, 1, 2, 3, 4]
between 5 and 10 : [5, 6, 7, 8, 9, 10]
greater than 10 : [11, 12, 13, 14, 15, 16, 17, 18, 19]
例3-27
:每天固定时间定时自动执行特定任务。
使用扩展库schedule实现更强大的任务调用功能
#使用扩展库schedule实现更强大的任务调用功能
#命令提示符下执行>pip install schedule
import time#导入模块
import schedule
def myJob1():
print('Job1:我30秒执行一次,每次执行3秒')
time.sleep(3)
#每隔30 秒 做myJob1
schedule.every(30).seconds.do(myJob1)#生成一个任务,执行在下面
def myJob2():
print('Job2:我1分钟执行一次,每次执行5秒')
time.sleep(5)
#每隔1 分钟 做myJob2
schedule.every(1).minutes.do(myJob2)
def myJob3():
print('Job3:我每天上午22:19执行一次,每次执行5秒')
time.sleep(5)
#每 天 10:47 做my Job3
schedule.every().day.at('22:19').do(myJob3)
def myJob4():
print('Job4:我每隔5到10秒(具体间隔随机)执行一次,每次执行3秒')
time.sleep(3)
#从5 秒 到10 秒 做myJob4
schedule.every(5).to(10).seconds.do(myJob4)
def myJob5():
print('Job5:我每周三晚上22:19执行一次,每次执行3秒')
time.sleep(3)
#每 周一 10:48 做myJob5
schedule.every().wednesday.at('22:19').do(myJob5)
while True:
schedule.run_pending()
例3-28
:给定一个包含若干随机整数的列表A,求满足0≤a≤b<n的A[b]-B[a]的最大值。
#给定一个包含若干随机整数的列表A,求满足0≤a≤b<n的A[b]-B[a]的最大值。
#简单的循环嵌套
def maxDifference1(lst): #定义一个函数,参数是一个列表
#负无穷大
diff=-float('inf') #diff=负无穷大
#enumerate返回位置和元素
for index,value in enumerate(lst[:-1]):
for v in lst[index+1:]:
t=v-value #后面的值-前面的值
if t>diff: #如果减完后比最大的差值还大
result=(value,v) #把此记下来
diff=t #现在最大的差值
return result[1]-result[0] #返回差值
#高大上的动态规划算法
def maxDifference2(lst):
diff=-float('inf') #负无穷大
minCurrent=lst[0] #列表第一个元素
for value in lst[1:]: #遍历列表中剩余的所有元素
if value<minCurrent:
minCurrent=value#找到当前的最小值
else:
t=value-minCurrent
if t>diff:
diff=t
result=(minCurrent,value)
return result[1]-result[0] #循环结束输出后减前最大差值
例3-34
:模拟蒙蒂霍而悖论游戏
假设你正在参见一个有奖游戏节目,并且有3道门可选:其中一个后面是汽车,另外来两个后面是山羊。你选择一个门,比如说1号门,支持人当然知道每个门后是什么并且打开了另一个门,比如说3号门,后面是一只山羊。然后主持人问你“你想改选2号门吗?”那么问题来了,改选的话会对你有利吗?
#模拟蒙蒂霍而悖论游戏
#randnt是闭区间
#randrange左闭右开
from random import randrange
def init():
result={i:'goat' for i in range(3)}#0,1,2都是山羊
r=randrange(3) #生成随机的编号0-2
result[r]='car' #随机生成的这个数字后面放车
return result#返回一个字典
def startGame():
#现在有的门就是上面的门
doors=init()
while True:
try:#确保用户输入的门号是有效的
#用户输入选择一个门
firstDoorNum=int(input('choose a door to open:'))
assert 0<=firstDoorNum<=2 #确认输入的数字是0-2之间
break
except:
print('Door number must be between {} and {}'.format(0,2))
#主持人查看另外两个门后的物品情况
#字典的键-用户输入的门号,就是剩下的两个门
for door in doors.keys()-{firstDoorNum}:
if doors[door]=='goat': #如果这个门后是山羊
print('"goat" behind the door',door)
#获取第三个门号,让玩家纠结
#所有门-主持人让打开的门-用户开始选择的门,就是剩下的最后一个门
thirdDoor=(doors.keys()-{door,firstDoorNum}).pop()
#问用户想不想改选第三个门
change=input('Do you want to switch to {}?(y/n)'.format(thirdDoor))
finalDoorNum=thirdDoor if change=='y' else firstDoorNum
if doors[finalDoorNum]=='goat':
return 'I Win!'
else:
return 'You Win'
#测试
while True:
print('='*30) #输出30个等于号
print(startGame()) #启动一次游戏
#游戏结束问一下,是否再玩一次
r=input('Do you wnat to try once more?(y/n)')
if r=='n':
break
参考:
Python控制结构1:条件表达式与常见选择结构_哔哩哔哩_bilibili
Python控制结构2:选择结构例题解析_哔哩哔哩_bilibili
Python控制结构3:循环结构语法与优化建议_哔哩哔哩_bilibili
Python控制结构4:循环结构例题解析1_哔哩哔哩_bilibili
Python控制结构5:循环结构例题解析2_哔哩哔哩_bilibili
Python控制结构9:循环结构例题讲解6_哔哩哔哩_bilibili