python选择与循环(5)

吉吉:

OC](选择与循环)

条件表达式

  • 在选择和循环结构中,都需要根据条件表达式的值确定下一步的执行流程。

True与False的判定

  • 条件表达式的值只要不是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 = []
>>> if a:   #空列表视为False
   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

条件表达式中的常用运算符

  • 关系运算符:>、<、==、<=、>=、!=,可以连续使用,以减少代码量

>>> 1<2<3
True
>>> 1<2>3
False
>>> 1<3>2
True
  • 测试运算符:in、not in、is、is not

注意:==与is的区别
==是比较操作符,用来比较判断两个对象的value(值)是否相等。
is也被叫做同一性运算符,用来比较判断的是对象间的唯一身份标识id是否相同。


>>> x=3
>>> y=3
>>> x==y
True
>>> x is y
True
>>> x=[1,2,3]
>>> y=[1,2,3]
>>> x==y
True
>>> x is y
False
  • 逻辑运算符“and”和“or”以及关系运算符,具有短路求值或惰性求值的特点,只计算必须计算的表达式的值。从而减少不必要的计算和判断。
  • 在设计条件表达式时,如果能够大概预测不同条件失败的概率,并将多个条件根据“and”和“or”运算的短路求值特性进行组织,可以大幅度提高程序运行效率。
  • 另外,在Python中,条件表达式中不允许使用赋值运算符“=”,避免了其他语言中误将关系运算符“==”写作赋值运算符“=”带来的麻烦,例如下面的代码,在条件表达式中使用赋值运算符“=”将抛出异常,提示语法错误。

>>> if a=3:
SyntaxError: invalid syntax
>>> if (a=3) and (b=4):	
SyntaxError: invalid syntax

选择结构

单分支选择结构

  • 格式:
    if 表达式: #冒号不可缺少,下面的语句块要缩进
    语句块
    表达式与True等价,语句块执行,否则不执行。

  • 输入使用空格分隔的两个整数,按升序输出。


x = input('Input two number:')
a, b = map(int, x.split())
if a > b:
   a, b = b, a   #序列解包,交换两个变量的值
print(a, b)

split():拆分字符串。通过指定分隔符对字符串(默认为空格)进行切片,并返回分割后的字符串列表(list)

双分支结构

格式:
if 表达式:
语句块1
else:
语句块2


>>> chTest = ['1', '2', '3', '4', '5']
>>> if chTest:  
	 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 random.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)
NameError: name 'random' is not defined
>>> import random
>>> x = math.sqrt(9) if 2>3 else random.randint(1, 100)

多分支结构

格式:
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'	

选择结构的嵌套

  • 格式:
    if 表达式1:
    语句块1
    if 表达式2:
    语句块2
    else:
    语句块3
    else:
    if 表达式4:
    语句块4

注意:缩进必须要正确并且一致。

  • 使用嵌套的选择结构实现百分制成绩到等级制的转换

    def func(score):
    degree = ‘DCBAAE‘ #[90,99]区间和100都对应A
    if score > 100 or score < 0:
    return ‘wrong score.must between 0 and 100.’
    else:
    index = (score - 60)//10#整除10
    if index >= 0: #60分以上的成绩
    return degree[index]
    else:
    return degree[-1] #60分以下的成绩对应F

构建跳转表实现多分支选择结构

  • 使用列表、元组或字典可以很容易构建跳转表,在某些场合下可以更快速地实现类似于多分支选择结构的功能。

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)
if func:
func()
else:
print('Wrong integer.')

选择结构应用

  • 面试资格确认。

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%4000 or (year%40 and year%100!=0): #判断是否为闰年
    day_month[1] = 29

    if month==1:
    print(day)
    else:
    print(sum(day_month[:month-1])+day)

说明:time.localtime([secs]):将一个时间戳转换为当前时区的struct_time, struct_time元组共有9个元素

  • python 中与时间处理相关的模块包括 time、datetime、以及 calendar

其中闰年判断也可以直接使用calendar模块的方法。


>>> calendar.isleap(2016)
True
>>> calendar.isleap(2015)
False
  • 或者使用datetime模块提供的功能来直接计算今天是今年的第几天

>>> datetime.date.today().timetuple().tm_yday
302
>>> datetime.date(2018,10,25).timetuple().tm_yday
298

请自行查阅datetime模块使用方法

  • datetime还提供了其他功能

>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2015, 12, 6, 16, 1, 6, 313898)
>>> now.replace(second=30)  #替换日期时间中的秒
datetime.datetime(2015, 12, 6, 16, 1, 30, 313898)
>>> now+datetime.timedelta(days=5) #计算5天后的日期时间
datetime.datetime(2015, 12, 11, 16, 1, 6, 313898)
>>> now + datetime.timedelta(weeks=-5)  #计算5周前的日期时间
datetime.datetime(2015, 11, 1, 16, 1, 6, 313898)

循环结构

  • Python提供了两种基本的循环结构语句——while语句、for语句。
  • while循环一般用于循环次数难以提前确定的情况,也可以用于循环次数确定的情况。
  • for循环一般用于循环次数可以提前确定的情况,尤其是用于枚举序列或迭代对象中的元素。

一般优先考虑使用for循环。

  • 相同或不同的循环结构之间都可以互相嵌套,实现更为复杂的逻辑。
  • for循环与while循环

while 条件表达式:
	循环体
[else: #如果循环由break跳出则不执行else内部代码
	else子句代码块]


for 取值 in 序列或迭代对象:
	循环体
[else:
else子句代码块]

循环结构的优化

  • 为了优化程序以获得更高的效率和运行速度,在编写循环语句时,应尽量减少循环内部不必要的计算,将与循环变量无关的代码尽可能地提取到循环之外。对于使用多重循环嵌套的情况,应尽量减少内层循环中不必要的计算,尽可能地向外提。
  • 优化前的代码:
    #生成由1,2,3,4组成的所有3位数,为观察效率重复1000次

digits = (1, 2, 3, 4)

for i in range(1000):  #假设执行1000次
result = []
for i in digits:
for j in digits:
for k in digits:
result.append(i*100+j*10+k) # 循环内部被重复计算
  • 优化后的代码:

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 #用内部变量直接指向该模块函数
start = time.time()
for i in range(10000000):
loc_sin(i)
print('Time Used:', time.time()-start)

break和continue语句

  • break语句在while循环和for循环中都可以使用,一般放在if选择结构中,一旦break语句被执行,将使得整个循环提前结束。
  • continue语句的作用是终止当前循环,并忽略continue之后的语句,然后回到循环的顶端,提前进入下一次循环。
  • 除非break语句让代码更简单或更清晰,否则不要轻易使用。
  • 下面的代码用来计算小于100的最大素数,注意break语句和else子句的用法。

for n in range(100, 1, -1): #遍历范围是[100,2],由大到小遍历


for i in range(2, n):
		if n%i == 0:
			break
else:
		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 后不执行,i不变成死循环

永不结束的死循环,Ctrl+C强行终止。

  • 这样子就不会有问题

>>> for i in range(10):   #遍历自动修改i值
	  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)
10416692 : 0
10416680 : 1
10416668 : 2
10416656 : 3
10416644 : 4
10416632 : 5
10416620 : 6

打印九九乘法表。


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()

说明:ljust(n) 方法返回一个原字符串左对齐,并使用空格填充至指定长度为n的新字符串。

  • 编写程序,计算组合数C(n,i),即从n个元素中任选i个,有多少种选法。
    根据组合数定义,需要计算3个数的阶乘,在很多编程语言中都很难直接使用整型变量表示大数的阶乘结果,虽然Python并不存在这个问题,但是计算大数的阶乘仍需要相当多的时间。本例提供另一种计算方法:以Cni(8,3)为例,按定义式展开为Cni(8,3)=8!/3!/(8-3)!=(87654321) /(321)/ (5432*1),对于(5,8]区间的数,分子上出现一次而分母上没出现;(3,5]区间的数在分子、分母上各出现一次;[1,3]区间的数分子上出现一次而分母上出现两次。

def Cni1(n,i):
if not (isinstance(n,int) and isinstance(i,int) and n>=i):
print('n and i must be integers and n must be larger 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
	return int(math.factorial(n)/math.factorial(i)/math.factorial(n-i))
>>> Cni2(6,2)
15
  • 还可以直接使用Python标准库itertools提供的函数。

>>> import itertools
>>> len(tuple(itertools.combinations(range(60),2)))
1770
  • itertools还提供了排列函数permutations()。

>>> import itertools
>>> for item in itertools.permutations(range(1,4),2):
	print(item)
	
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)
发布了44 篇原创文章 · 获赞 82 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/weixin_41503009/article/details/85651886
今日推荐