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

 

posted @ 2017-12-30 10:29  xy小崽子  阅读(858)  评论(0编辑  收藏  举报