第四章 程序控制结构
结构化程序设计方法的主要思想包括以下原则:自顶向下、逐步求精、模块化结构开发
三种基本结构:顺序、分支、循环
需要记的ASCII码:
- 1->49
- a->97
- A->65
- 换行符->10
易错:
- else子句放在for或者while循环后面,如果循环正常结束(即没有被break),则执行else语句,否则不执行。
分支结构
if语句:
if condition1:
statement_block_1
elif condition2:
statement_block_2
...
else:
statement_block_n
循环结构
break语句:提前终止当前循环,接着执行循环之后的语句
continue语句:提前结束本轮的循环,接着执行下一轮循环
与C语言类似,比较不一样的地方是特殊循环:列表解析
>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x*x for x in range(10) if x*x<50]
[0, 1, 4, 9, 16, 25, 36, 49]
>>> [x+y for x in range(3) for y in range(3)]
[0, 1, 2, 1, 2, 3, 2, 3, 4]
约瑟夫生死小游戏:30个人报数,报到9的人下船
count = 0
lst = [i for i in range(1,31)]
while len(lst) > 15:
count += 1
t = lst.pop(0)
if count != 9:
lst.append(t)
else:
count = 0
print('{}号下船了'.format(t))
运行结果:
9号下船了 18号下船了 27号下船了 6号下船了 16号下船了 26号下船了 7号下船了 19号下船了 30号下船了 12号下船了 24号下船了 8号下船了 22号下船了 5号下船了 23号下船了
统计字符串中出现的单词以及出现的次数
st1=input("str1=")
lst=st1.split()
d=dict()
for item in lst:
d[item]=d.get(item,0)+1
aList=list(d.items())
for x,y in aList:
print(x,y)
运行结果:
str1= Python C++ Java Python Python JavaPython 3 C++ 1 Java 2
第五章 函数
参数传递
字符串、元组、数值等是不可更改的对象,而列表、字典则是可以修改的对象。
若函数传递的参数是不可更改的对象,则形参的改变不影响实参;
若传递的参数是可改变的,则形参的改变会影响实参。
1、如果在函数内部对形参重新赋值,则形参的值不会影响实参;
def changeInt(a):
a=10
print('函数内部的变量值:',a)
b=2
changeInt(b)
print('函数外部的变量值:',b)
运行结果:
函数内部的变量值: 10 函数外部的变量值: 2
2、如果在函数内部对形参进行修改(只改变部分元素),则形参的值会影响实参;
def changeInt(newlist):
newlist=[1,2,3]
print('函数内取值:',newlist)
return
oldlist=[10,20,30]
changeInt(oldlist)
print('函数外取值:',oldlist)
运行结果:
函数内取值: [1, 2, 3] 函数外取值: [10, 20, 30]
def changeInt(newlist):
newlist[0]=15
print('函数内取值:',newlist)
return
oldlist=[10,20,30]
changeInt(oldlist)
print('函数外取值:',oldlist)
运行结果:
函数内取值: [15, 20, 30] 函数外取值: [15, 20, 30]
3、如果希望实参不受形参的影响,可以在实参传递前先给实参复制副本,这样形参在函数内的修改就不会影响外部的实参。
def changeme(newlist):
newlist.append(4)
print('函数内部取值:',newlist)
return
oldlist=[1,2,3]
bk_oldlist=oldlist[:]
changeme(oldlist)
print('函数外oldlist取值:',oldlist)
print('函数外bk_oldlist取值:',bk_oldlist)
运行结果:
函数内部取值: [1, 2, 3, 4] 函数外oldlist取值: [1, 2, 3, 4] 函数外bk_oldlist取值: [1, 2, 3]
注意:bk_oldlist=oldlist[:]将oldlist浅拷贝给bk_oldlist,它们并不引用同一个对象,但如果将拷贝语句改为bk_oldlist=oldlist,则它们引用同一个对象,bk_oldlist也会改变。
- 函数定义时默认参数必须放在非默认参数之后,否则传递实参时Python解释器无法判断传递的实参时修改了的默认值还是对应了后面的参数。
参数类型
关键字参数
使用关键字参数允许函数调用时参数的顺序与声明不一致,可以解决参数传错的问题。
例如:
def printInfo(sid,name,sex,age):
print("sid:",sid)
print("name:",name)
print("sex:",sex)
print("age",age)
return
age=12
sex="female"
name="xiaoxiao"
sid="1117"
print("——————必需参数类型——————")
printInfo(age,sex,name,sid)
print("——————关键字参数类型——————")
printInfo(age=12,sex="female",name="xiaoxiao",sid="1117")
——————必需参数类型——————
sid: 12
name: female
sex: xiaoxiao
age 1117
——————关键字参数类型——————
sid: 1117
name: xiaoxiao
sex: female
age 12
默认参数
注意:默认参数必须放在其他非默认参数的后面。
def printInfo(sid,name,sex,age=12):#默认参数age为12
print("sid:",sid)
print("name:",name)
print("sex:",sex)
print("age",age)
return
print("——————不采用默认参数的值——————")
printInfo(age=16,sex="female",name="xiaoxiao",sid="1117")
print("——————采用默认参数的值——————")
printInfo(sex="female",name="xiaoxiao",sid="1117")
——————不采用默认参数的值——————
sid: 1117
name: xiaoxiao
sex: female
age 16
——————采用默认参数的值——————
sid: 1117
name: xiaoxiao
sex: female
age 12
可变长参数
在Python中,可能需要一个函数能处理比当初声明时更多的参数,这时在函数定义时,可以声明一个可变长参数(本质上是一个元组)。
def printInfo(sid,name,*otherInfo):
print("sid:",sid)
print("name:",name)
print(otherInfo)
return
printInfo('1211','xiongmao',23,'male')
打印结果:
sid: 1211
name: xiongmao
(23, 'male')
可变长参数也支持接受关键词参数。
def printInfo(sid,name,**otherInfo):
print("sid:",sid)
print("name:",name)
for x,y in otherInfo.items():
print(x,":",y)
return
otherInfo={"age":12,"sex":"female","height":160}
printInfo('1211','xiongmao',**otherInfo)
sid: 1211
name: xiongmao
age : 12
sex : female
height : 160
变量作用域
访问顺序是局部变量(Local)——非局部非全局变量(Enclosing)——全局变量(Glogal)——Python内置变量/关键词(Built-in)
匿名函数
Lst=[19,80,9,11,96,12]
print(sorted(Lst,key=lambda item:item,reverse=True))#按item大小排序
print(sorted(Lst,key=lambda item:len(str(item)),reverse=True))#按字符串长度排序
print(sorted(Lst,key=lambda item:(len(str(item)),item),reverse=False))#先按照长度,再按大小排序
打印结果:
[96, 80, 19, 12, 11, 9]
[19, 80, 11, 96, 12, 9]
[9, 11, 12, 19, 80, 96]
常用标准函数库
math.pi | 常数 |
math.gcd(a, b) | 求a和b的最大公约数 |
math.sqrt( ) | 求平方根 |
os.getcwd( ) | 获得当前工作目录 |
os.chdir( ) | 更改当前工作目录 |
os.mkdir( ) | 在当前目录下创建新目录 |
os.listdir( ) | 列出当前目录下文件或文件夹 |
os.rmdir( ) | 删除目录 |
os.remove( ) | 删除指定文件 |
random.random( ) | 生成一个[0,1.0]之间的随机小数 |
random.uniform(a, b) | 生成一个a到b之间的随机小数 |
random.randint(a, b) | 生成一个a到b之间的随机整数 |
实验思考题
1、程序控制结构思考题
#4.1 q1:判断输入数的奇偶性number=eval(input("请输入一个数:")) if(number%2==0): print(number,'是偶数') else: print(number,'是奇数')
#4.1 q2:输入矩形长和宽,判断是否为正方形,并输出其面积length=eval(input("请输入矩形的长:")) width=eval(input("请输入矩形的宽:")) if(length==width): print("该矩形是正方形") else: print("该矩形不是正方形") print("该矩形的面积为",length*width)
#4.1 q3:输入一个数,判断是否为完全平方数number=eval(input("请输入一个数:")) for i in range(2,number): if(i**2==number): print(number,'是完全平方数') break; else: if(i==int(number/2)): print(number,'不是完全平方数')
#4.1 q4:将分数转化为等级score=eval(input("请输入成绩:")) if(score>=90): print('等级为A') elif(80<=score<90): print('等级为B') elif(70<=score<80): print('等级为C') elif(60<=score<70): print('等级为D') else: print('等级为E')
#4.2 q1:分别用while和for语句,实现阶乘功能''' for语句: number=eval(input("输入一个整数:")) result=1 for i in range(1,number+1): result*=i print(number,'的阶乘是',result) ''' number=eval(input("输入一个整数:")) i=1 result=1 while(i<=number): result*=i i=i+1 print(number,'的阶乘是',result)
#4.2 q2:(重点)求最大公约数和最小公倍数(辗转相除法)
num1=eval(input("请输入第一个数字:")) num2=eval(input("请输入第二个数字:")) if(num1<num2): smaller=num1 else: smaller=num2 for i in range(smaller,0): if((num1%i==0)and(num2%i==0)): result=i break print(num1,'和',num2,'的最大公约数为:',result) print(num1,'和',num2,'的最小公倍数为:',int(num1*num2/result))
#4.2 q3:利用循环嵌套实现查找指定范围内质数a=eval(input("输入区间最小值:")) b=eval(input("输入区间最大值:")) count=0 for i in range(a,b+1): for j in range(2,i): if(i%j==0): break if(j==i-1): print(i,end=' ') count+=1 if(count%5==0): print()
2、函数思考题
1、统计字符串中每个字母出现的次数,按照字母出现频率从高到底排序输出
def count_letters(text):
letter_counts={chr(i):0 for i in range(ord('a'),ord('z')+1)}
text=text.lower()
for char in text:
if char in letter_counts:
letter_counts[char]+=1
sorted_counts=sorted(letter_counts.items(),key=lambda x:x[1],reverse=True)
return sorted_counts
text="ArkNights Hello Doctor qazaqwsxxsw"
sorted_letter_counts=count_letters(text)
for letter,count in sorted_letter_counts:
print(f"{letter}:{count}")
reverse=True:降序排序
2、调换字典中的键和值,假设值没有重复
def reverse_dict(dic):
out={}
for k,v in dic.items():
out[v]=k
keys=sorted(out.keys(),reverse=True)
for i in keys:
print(i,out[i])
return out
dic={'wb':1001,'ml':1003,'xl':1004}
reverse_dict(dic)
(复习)
3、输出前N个丑数
丑数:只包含质因子2、3和5的正整数
def isUglyNumber(x):
if x == 1:
return True
else:
for i in [2, 3, 5]:
while x % i == 0:
x //= i
return x==1
def getUglyNumber(N, lst):
count = 0
x = 1
while count < N:
if isUglyNumber(x):
lst.append(x)
count += 1
x += 1
return lst
if __name__ == "__main__":
N = int(input("please enter the N(N>0):"))
lst = []
result = getUglyNumber(N, lst)
print(result)
4、输入日期,转化为该日期对应是这一年的第几天
def count_days(someday):
months=(0,31,59,120,151,181,212,243,273,304,334)
year=int(someday[0:4])
month=int(someday[4:6])
day=int(someday[6:])
if 1<=month<=12:
basicday=months[month-1]#从0开始
else:
print("data error")
basicday+=day
leapyear=False#将True改为False
if year%4==0 and (year%100!=0 or year%400==0):
leapyear=True
if leapyear and month>2:
basicday+=1
return basicday
if __name__=="__main__":
someday=input("Enter the data in the format of 20171231:")
basicday=count_days(someday)
print("{0:} is the {1:}st/rd/th day of this year".format(someday,basicday))
5、编写颠倒数组元素的函数,传入参数包括数组,起始位置和终止位置
def rverseArray(arr,start,end):
arr1=arr[::-1]
for i in range(start,end+1):
arr[i]=arr1[i]
return arr
if __name__=="__main__":
arr=[1,2,3,4,5,6,7]
print("-----原始数组-----")
for i in arr:
print(i,end=" ")
print()
print("-----颠倒数组-----")
rverseArray(arr,2,4)
for i in arr:
print(i,end=" ")
6、查找1000以内的超级素数
超级素数:本身以及去掉末尾还是素数,如此循环
def judge(number):
for i in range(2,number):
if number%i==0:
return False
return True
def superJudge(number):
while number>0:
if judge(number):
number=int(number/10)
else:
return False
return True
if __name__=="__main__":
for number in range(1,1001):
if superJudge(number):
print(number,end=" ")
7、给出三个正整数k,a,b,查找出正整数n,满足a<=n<=b,且k*f(n)=n,定义f(n)为其各位数字的平方和
习惯了C语言版:
def f(n):
result=0
while(n!=0):
result+=(n%10)**2
n=int(n/10)
return result
def fun(k, a, b):
for n in range(a,b+1):
if k*f(n)==n:
print(n)
if __name__=='__main__':
k, a, b=input('请输入k,a,b:').split()
k=int(k)
a=int(a)
b=int(b)
fun(k, a, b)
python版:
def f1(n):
return sum(int(digit)**2 for digit in str(n))
def f2(k,a,b):
result=[]
for n in range(a,b+1):
if k*f1(n)==n:
#print(n),可以把每个结果都打出来,也可以以列表返回再打印
result.append(n)
return result
k=51
a=5000
b=10000
print(f2(k,a,b))
8、编写四个函数,分别打印出左正、左倒、右正、右倒三角的九九乘法表
def fun1():
print('左正三角乘法表')
for i in range(1,10):
for j in range(1,i+1):
print('{}*{}={:<2}'.format(i,j,i*j),end=' ')
print()
def fun2():
print('右正三角乘法表')
for i in range(1, 10):
for k in range(1, 10-i):
print(' ', end='')
for j in range(1, i+1):
print('{}*{}={:<2}'.format(i, j, i*j), end=' ')
print()
def fun3():
print('左倒三角乘法表')
for i in range(1,10):
for j in range(i,10):
print('{}*{}={:<2}'.format(i,j,i*j),end=' ')
print()
def fun4():
print('右倒三角乘法表')
for i in range(1, 10):
for k in range(1,i):
print(' ', end='')
for j in range(i, 10):
print('{}*{}={:<2}'.format(i, j, i*j), end=' ')
print()
if __name__=='__main__':
fun1()
fun2()
fun3()
fun4()
9、四舍五入保留两位小数
avg=101.376
avg=avg*100
t=int(avg+0.5)
avg=t/100
print(avg)
输出结果:101.38
10、
def contact(*args,sep="/"): return sep.join(args) print(contact("hello","python","java",sep=".")) print(contact("hello","python","java"))
比较二者的输出结果:
hello.python.java hello/python/java
11、十进制转换为其他指定进制
def foo(num,base):
if(num>=base):
foo(num//base,base)
print(num%base,end='')
numA=int(input("请输入一个十进制的数字"))
numB=int(input("请输入指定进制"))
foo(numA,numB)
12、分鱼问题:A、B、C、D、E五人一起捕鱼,依次把鱼分成五份,并把一条多余的鱼丢掉,拿走五份中的一份。则他们至少捕到多少条鱼?
fish=1
while True:
total,enough=fish,True
for i in range(5):
if(total-1)%5==0:
total=(total-1)//5*4
else:
enough=False
break
if enough:
print(f"总共有{fish}条鱼")
break
fish+=1
运行结果:
总共有3121条鱼
13、(重点)冒泡排序/插入排序
冒泡排序:比较相邻元素的大小
def bubbleSort(arr):
n=len(arr)
for i in range(n):
for j in range(0,n-i-1):
if arr[j]>arr[j+1]:
arr[j],arr[j+1]=arr[j+1],arr[j]
arr=[23,16,39,27,43,12,11,9,80]
print(arr)
bubbleSort(arr)
print(arr)
运行结果:
[23, 16, 39, 27, 43, 12, 11, 9, 80]
[9, 11, 12, 16, 23, 27, 39, 43, 80]
插入排序:依次拿出一个数,与原本在它前面的数比较,从而依次确定前i个数的顺序。
def insertSort(arr):
n=len(arr)
for i in range(n):
x=arr[i]
for j in range(i,-1,-1):
if x<arr[j-1]:
arr[j]=arr[j-1]
else:
break
arr[j]=x
14、递归函数实现二分查找
def binarySearch(arr,l,r,x):
if r>=l:
mid=int(l+(r-l)/2)
if arr[mid]==x:
return mid
elif arr[mid]>x:
return binarySearch(arr,l,mid-1,x)
else:
return binarySearch(arr,mid+1,r,x)
else:
return -1
arr=[9, 11, 12, 16, 23, 27, 39, 43, 80]
x=eval(input("输入要查找的元素"))
result=binarySearch(arr,0,len(arr)-1,x)
if result!=-1:
print("%d"%result)
else:
print("该元素不存在")