python(2): If/for/函数/try异常/调试/格式输出%
(一) if
if a1==a2: print('ok')
if: else:
if: elif: ... else: 注意缩进
猜数字游戏
from random import randint x=randint(0,300) digit= int(input('please input a number between 0-300:')) if digit==x: print('bingo!') elif digit>x: print('too large, please try again') else: print('too small, please try again')
(二) for 循环
上述只能猜一次数字, 如何猜多次? for 循环
range(start, end, step=1), list(range(3,11,2))=[3,5,7,9]
range(start, end), 默认step=1, list(range(3,5))=[3,4]
range(end), 默认start=0, step=1, list(range(4))=[0,1,2,3].
1.while 语句(循环次数不确定)
s=0 j=1 while j<10: s=s+j j=j+1 print(s) # 45
2. for (循环次数确定, 遍历数据集中的成员)
f='python' for x in f: print(x) # 输出 p yt h o n
用range
for i in range(5): print(i, end=',') #0,1,2,3,4,
修改之前猜数字游戏设定猜3次
from random import randint x=randint(0,300) for cnt in range(3): digit= int(input('please input a number between 0-300:')) if digit==x: print('bingo!') elif digit>x: print('too large, please try again') else: print('too small, please try again')
用range创建列表, 生产器:
# 创建列表 [i for i in range(10)] Out[11]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [i+1 for i in range(10) if i%2==0] Out[12]: [1, 3, 5, 7, 9] # 生成器 (i for i in range(10)) Out[13]: <generator object <genexpr> at 0x000001D6BA07FF48>
break的运用
加和
s=0 j=1 while True: s=s+j j=j+1 if s>20: break print('j={},sum={}'.format(j,s)) # j=7,sum=21
2-100素数寻找
from math import sqrt j=2 while j<=100: i=2 k=int(sqrt(j)) while i<=k: if j%i==0 : break i=i+1 if i>k: print(j,end=' ') j=j+1 # 用for for i in range(2,10): flag=1 k=int(sqrt(i)) for j in range(2,k+1): # i=2, k=1,j会有问题 if i%j==0: flag=0 break if flag: # 不能j>k,跳出循环j不会+1, 比如i=7,j=2 break,跳出后仍是j=2,2>2不成立则不输出7,error, 因此引入flag print(i,end=',') i=i+1
continue 停止这一轮循环
猜数字游戏改进, 由用户自定义多少次停止
from random import randint x=randint(0,300) go='y' while go=='y': digit= int(input('please input a number between 0-300:')) if digit==x: print('bingo!') break elif digit>x: print('too large, please try again') else: print('too small, please try again') print('input y if you want to continue') go=input() print(go) else: print('goodbye!')
注意: else与while搭配, 这是python的特点, 如果循环从break终止, 跳出循环, 正常结束就执行else,
当你不行继续, 输入no, 也是会有 goodbye!
else 也可以与for 搭配, 用法与while一样.
问题: 下面代码输出什么?
for i in range(1, 10, 2): if i % 5 == 0: print("Bingo!") break else: print(i)
ans: bingo!
(三) 函数
def fun_name(x): 'apply operation + to argument' return(x+x) print(fun_name(2)) #4
判别素数的函数
from math import sqrt def isprime(x): if x==1: return False k=int(sqrt(x)) for i in range(2,k+1): if x%i==0: return False return True for i in range(2,20): if isprime(i): print(i,end=' ')
函数的默认参数(函数定义时使用)
def fun(x=True): # 默认参数值为true if x: print('x is a correct word') print('ok') fun() # 没有参数则默认为True ,输出x is a correct word ok
fun(False) # 有参数则按照这个参数来, 最后只输出ok
注意: 默认参数需要放在参数列表的最后!! , 否则会有歧义, 例如
def f(x,y=True): if y: print(x,'and y both correct') print(x,'is ok') f(68) # 默认传给x #68 and y both correct #68 is ok f(68,False) # 只输出68 is ok def f(y=True, x): if y: print(x,'and y both correct') print(x, 'is ok') f(False) # 报错! , False应该给x 还是y?
关键字参数: 当函数有很多输入参数时, 用关键字参数调用函数可以避免顺序搞错
def f(x,y): if y: print(x,'and y both correct') print(x,'is ok') f(y=2, x=1)
但是一旦用关键字参数, 后面都要用, 不可以f(y=1,2) !
多个函数套用
def add1(x): return(x+x) def add2(x): return(x+10) print(add2(add1(3))) # 16
传递函数
def add1(x): return(x+x) def add2(f,x): return(f(x)) print(add2(add1,10)) # 20
特殊的函数 lambda 匿名函数
r= lambda x :x**2 print(r(5)) #25 r= lambda x,y:x*2+y print(r(5,2)) #12
递归函数: 斐波那契数列 0,1,1,2,3,5,8,13...
def fib(n): if n==0 or n==1: return n else: return fib(n-1)+fib(n-2) print(fib(10)) # 55
递归的效率比较低, 不及循环.
实例1: 汉诺塔, 三个盘子a, b, c, a上有n 个盘子, 想要移动到c
n=1, 则直接从a 到c, n>1, 把n-1个盘子借助c移动到b, 接着a->c, 然后把b的n-1个盘子借助a移到c.
def hanoi(a,b,c,n): if n==1: print(a,'->',c) else: hanoi(a,c,b,n-1) print(a,'->',c) hanoi(b,a,c,n-1) print(hanoi('a','b','c',3))
得到移动过程
a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c
实例2: 阶乘
def fact(n): if n==0: return 1 else: return n*fact(n-1) print(fact(5)) #120
实例3: 字符串反转
def reverse(s): if s=='': return s else: return s[-1]+reverse(s[0:-1]) # 或者reverse(s[1:])+s[0] str='abcd' print(reverse(str)) # dcba
全局变量
def f(x): global a print(a) a=5 print(a+x) a=3 print(f(8)) # 13 print(a) # 5
少用全局变量
python的标准库函数
1.math库
查看math 库下面的函数
import math
math.pi, math.e, math.degrees(3.14), math.radians(180)
from math import* x=-2.3 print(ceil(x)) # -2 print(floor(x)) # -3 x=2.3 print(log(x)) # 以e为底 # 0.8329091229351039 print(sqrt(x)) # 1.51657508881031 print(exp(x)) # 9.974182454814718 print(log10(x)) # 0.36172783601759284 print(sin(x)) # 0.7457052121767203
2.os 库
import os
os.getcwd() # 获得当前工作目录 Out[33]: 'C:\\Users\\xuying_fall\\.spyder-py3' path='c:\\test' os.chdir(path) # 修改当前目录 os.rename('test.txt','test1.txt') # 重命名 os.remove('test1.txt') # 删除文件
读取文件的操作会在后续再详细介绍.......
3. random 库 import random
import random random.randint(1,100)# 产生随机整数1-100之间 random.randrange(0,10,2) # 产生随机整数 random.random() # 随机浮点数, 包含0, 不包含1.0 random.uniform(5,10) # 产生5-10均匀分布随机浮点数, random.sample(range(100),10) # 获取10个元素作为样本 [23, 28, 39, 82, 2, 87, 25, 36, 32, 88] a=[1,2,3,4] random.shuffle(a) # 将a 打乱顺序, 改变了a print(a) # [2, 4, 3, 1]
其他
from random import* seed(10) print(random()) # 0.5714025946899135, [0,1]之间的小数 seed(10) print(random()) # 0.5714025946899135 , #同一个seed下,产生的随机数是一样的
实例 monte_carlo 模拟pi 的近似值: 采用面积法进行,在[0,1]*[0,1]之间进行掷点, 计算到(0,0)之间的距离
from random import * from math import * tol=3000 # 总次数 cnt=0 # 用于计数 for i in range(1,tol): # 实际tol取不到 x,y=random(),random() # 可以一起赋值 d=sqrt(x**2+y**2) if d<=1.0: cnt+=1 pi=4*(cnt/tol) print('pi is about %.2f'%pi) # pi is about 3.18
4.datetime日期处理
from datetime import date print(date.today()) # 2018-11-24 from datetime import time tm=time(23,20,15) print(tm) # 23:20:15 from datetime import datetime dt=datetime.now() print(dt) # 2018-11-24 13:21:48.968220 # 格式转化, %a 本地简化的星期名称, %A本地完整的星期名称 print(dt.strftime('%a, %b %d %Y %H:%M ')) # # Sat, Nov 24 2018 13 :43 print(dt.strftime('%A, %b %d %Y %H:%M ')) # Saturday, Nov 24 2018 13 :44 dt1=datetime(2018,6,6,23,29) print(dt1) # 2018-06-06 23:29:00 ts=dt1.timestamp() # 把datetime转为全球统一的时间戳, print(ts)# 1971-1-1,0时刻记作0, 当前时间为从该时刻开始的秒数,1528298940.0 print(datetime.fromtimestamp(ts)) # 把时间戳转为本地的时间,2018-06-06 23:29:00
(四) 程序的异常处理
除数为0的情况, 异常为终止程序的进行
try except 语句
try: num1=int(input('enter the first number:')) num2=int(input('enter the second number:')) print(num1/num2) except ValueError: # ValueError异常类的名字 print('please input a digit!') # 没有异常就会忽略except 的语句 except ZeroDivisionError as err: #err存放错误原因 print('the second number cannot be zero') print(err) # 多个except 语句捕捉多个异常, 也可以写在一起 try: num1=int(input('enter the first number:')) num2=int(input('enter the second number:')) print(num1/num2) # 一个except 捕捉多个异常 except (ValueError,ZeroDivisionError) #err存放错误原因 print('invalid input!')
如果想捕捉所有的异常怎么办?
try: num1=int(input('enter the first number:')) num2=int(input('enter the second number:')) print(num1/num2) # 一个except 捕捉多个异常 except: print('something went wrong!')
enter the first number:a
something went wrong!
但是不知道出错原因, 怎么办? 用as 语句, 也可以添加else , 在一切正常的时候执行
try: num1=int(input('enter the first number:')) num2=int(input('enter the second number:')) print(num1/num2) # 一个except 捕捉多个异常 except Exception as err: #err存放错误原因 print('something went wrong!') print(err) else: print('All right')
上述如果有异常就结束程序, 如何多次尝试直到正确为止? 增加while True
while True: try: num1=int(input('enter the first number:')) num2=int(input('enter the second number:')) print(num1/num2) break # 一个except 捕捉多个异常 except Exception as err: #err存放错误原因 print('something went wrong!') print(err) else: print('All right')
try-except 除了跟着else 语句, 还可以跟着finally 语句, 无论是否异常都要执行!
while True: try: num1=int(input('enter the first number:')) num2=int(input('enter the second number:')) print(num1/num2) break # 一个except 捕捉多个异常 except Exception as err: #err存放错误原因 print('something went wrong!') print(err) finally: print('this round is over')
打开关闭文件
try: f=open('data.txt') for line in f: print(line,end=';') except IOError: print('cannot open the file') finally: f.close()
无论文件是否被正常打开, 最后都会关闭, 但是当文件打开出错时, f 会有问题, 因此f.close() 报错
如何解决?? with open('data.txt') as f: 就不会有问题了, 这种方式打开文件不需要最后加close
try: with open('data.txt') as f: for line in f: print(line,end=';') except IOError: print('cannot open the file')
实例: 二次函数求根
import math def main(): print('this programe is to find the real roots of equation\n') try: a,b,c=eval(input('please input three coefficients:')) dd=math.sqrt(b**2-4*a*c) r1=(-b+dd)/(2*a) r2=(-b-dd)/(2*a) print('the real roots are:',r1,r2) except : print('\n something went wrong, sorry') finally: print('\n maybe another try or quit') # 无论是是否出错都会执行的语句 main() # 调用函数
注意: 输入 1,2,3 注意: 输入格式要和代码中a,b,c 一致, 要用逗号!! , 这里就不能输入1 2 3
please input three coefficients:2,3,1
the real roots are: -0.5 -1.0 # 这里的输出没有逗号!!
maybe another try or quit
(五) 程序调试
在代码的前面空白处双击一下就可以设置断点, 调试可以实现运行到断点所在行
依次: 运行, 运行当前行
第五个: 运行到下一个断点处, 最后一个按钮表示停止调试
(六) 格式化输出%
print('%c'%98) # b print('%d+%d=%d'%(1,2,1+2)) print('%5.3f'%12.34) # 12.340 保留三位小数 s=1001.23 print('the total sum is %.2f'%s) # the total sum is 1001.23
实例
result=1.09023 print('结果为:{}'.format(result)) print('{}'.format(result)) #结果为:1.09023 print('%.3f'%result) #浮点型保留三个小数, 1.090 print('%.0f'%result) #不保留小数, 1 print('%d'%result)# 1
(七)重要函数
排序, 最值, 列举...
x=[1,3,5,2] print (max(x)) # 5 print(sorted(x)) # [1, 2, 3, 5] , x没有改变 print(list(enumerate(x))) # [(0, 1), (1, 3), (2, 5), (3, 2)]
map(f(x), [x1,x2])=[f(x1),f(x2)]
上述已经介绍过了lambda的强大, 还有一个filter函数也很厉害
print (filter(None,[0,1,2,False,True])) #[1, 2, True]选出true项 # 得到的只是<filter object at 0x0000021870326940> # 加一个list就可以输出了 print (list(filter(None,[0,1,2,False,True]))) #[1, 2, True]选出true项 print(list(filter(lambda x:x%2,range(10)))) #[1, 3, 5, 7, 9]选出奇数项, print(list(map(lambda x:x**2+1,range(4)))) # [1, 2, 5, 10] 集合映射逐一计算
Python 的精简
a=[' ds','dd '] b=[i.strip() for i in a] #去空格, 精简的循环写法 print(b) # ['ds', 'dd'] print (list(map(str.strip,a))) #两者等价 ['ds', 'dd'] , str表示库 vec=[(1,2),(3,4)] c=[ j for i in vec for j in i] print (c) #每个元素取出来 [1, 2, 3, 4] print([(x,y)for x in range(2) for y in range(2)]) #得到[(0, 0), (0, 1), (1, 0), (1, 1)]