函数的多个返回值
def hello():
return "hello","world"
result = hello()
print(result,type(result))#('hello', 'world') <class 'tuple'>
返回的多个值是元组类型
res1,res2 = hello()
print(res1,res2) #hello world
函数多个返回值的练习
i = 2
print(isinstance(i,int)) #True 判断数据类型
函数名get_max_min_avg()
函数可以传递任意多个数字, 并且保证是整形或者浮点型;
如果满足条件, 返回最大值, 最小值,和平均值;
如果不满足条件, 返回None
def is_int_float(t):
for i in t:
if not isinstance(i,(int,float)):
return False
else:
return True
def get_max_min_avg(*args):
if is_int_float(args):
return max(args),min(args),sum(args)/len(args)
print(get_max_min_avg(12,2,3,23,34))
形参的顺序
常用:必选 》 默认 》 可变(元组类型) 》 关键字(字典类型)
特例:可选参数 》 默认参数
易错点:形参的默认参数类型,必须是不可变数据类型,如果是可变的函数执行一次,默认参数的值就会改变一次。
def fun(l=[]):
l.append("hello")
return l
print(fun()) # ['hello']
print(fun()) #['hello', 'hello']
print(fun()) #['hello', 'hello', 'hello']
高级特性
迭代
主要是字典的迭代
d = dict(a=1,b=2)
for k,v in d.items():
print(k,v)
判断一个对象是否可迭代
首先需要倒入模块
from collections import Iterable
print(isinstance(1,Iterable)) #False
print(isinstance('hello',Iterable))#True
print(isinstance({1,2,3},Iterable))#True
高级特性
列表生成式 :生成列表的公式
列表生成式的四种写法
最简单的,只有简单的for循环
[i for i in range(10)]
for循化里面嵌套有if判断
[i for i in range(10) if i%2==0]
for循环里面有if和else
[ i**2 if i%2==0 i**3 for i in range(10)]
for循环里面嵌套for循环
[ i+j for i in 'abc' for j in '123']
列表生成式的练习
利用列表生成式随机生成100个IP地址
import random #随机生成一个整数的模块
list = ['172.25.254.' + str(random.randint(1,255)) for i in range(100)]
print(list)
print(len(list))
1~100之间能被三整除的数的平方
def is_div_three(n):
if n % 3 ==0:
return True
list = [i**2 for i in range(1,101) if is_div_three(i)]
print(list)
找出/etc/目录中所有以.conf结尾的文件,并把这些文件名转化为大写的文件名
import os #将目录中的文件名转换为列表的模块
list = [i.upper() for i in os.listdir('/etc') if i.endswith('.conf')]
print(list)
给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。输入值小于1000。
def is_num(i):
if i <= 0:
return False
elif i ==1 or i == 2:
return True
else:
for n in range(2,i):
if i%n == 0:
return False
else:
return True
num = int(input("请输入一个正整数:"))
list = [item for item in range(num) if is_num(item)]
list1 = [d for d in list if num-d in list and num -d >= d]
print(list1)
print(len(list1))
集合生成式
d = dict(a=6, b=2, c=3, e=6)
print({i for i in range(10) if i%3==0})
print({i for k,i in d.items() if i%3==0})
字典生成式
service = {
'http': 80,
'mysql': 3306,
'ssh': 22
}
#需求一将所有key值变为大写
#利用列表生成器的方法
services = {k.upper():v for k,v in service.items()}
#大小写key值合并, 统一以小写key值输出
d = dict(a=1,b=2,c=3,A=1,B=4)
print({k.lower():d.get(k.lower(), 0)+d.get(k.upper(),0) for k,v in d.items()})
# 需求3: 把字典的key和value值调换;
d1 = {'name': 'fentiao', 'gender': 'male'}
print({v:k for k,v in d1.items()})
生成器
将列表生成式改为生成器
li = [i for i in range(100) if i%2==0]
# 生成器
g = (i for i in range(100) if i%2==0)
查看生成器的两种方法
在python3中用g.next()方法
在python2中用g.next()
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(next(g))
生成器是可迭代的
可以通过这种方法查看
from collections import Iterable
print(isinstance(g, Iterable))
for 循环的底层原理
g = (i for i in range(3))
while True:
try: #异常处理器
print(g.__next__())
except:
break
菲波拉契数列
def fib(num): # num=5
a, b, count = 0, 1, 1 # a=0, b=1
while count <= num:
yield b # 1
a, b = b, a + b # a=1, b=1
count += 1
g = fib(10) #如果函数中有yield关键字,返回一个生成器对象,目前不执行函数内容
print(g.__next__()) #当遇到g.__next__()方法时执行函数,当遇到yield关键字是执行结束,print(g.__next__())的是yield后面的值
print(g.__next__()) #当再次调用g.__next__()方法时,函数接着上次停止的地方执行,遇到yield停止
print(g.__next__())
g.close #关闭生成器
生成器的应用,迷你机器人的聊天
def chat_robot():
res = ''
while True:
received = yield res
if 'age' in received or "年龄" in received:
res = "年龄保密!"
elif 'name' in received or '姓名' in received:
res = '我是小冰.....'
elif 'money' in received or '钱' in received:
res = '没钱....'
else:
res = '我不知道你在说什么, 请换种说法!'
def main():
Robot = chat_robot()
Robot.__next__()
while True:
send_data = input("粉条>>")
if send_data == 'q' or send_data == 'qu`it':
print("我也要休息了....")
break
robot_data = Robot.send(send_data)
print("小冰>>", robot_data)
main()
高阶函数
map
m = map(mypower, [1,2,3])
#map是可迭代的
print(m,type(m),isinstance(m, Iterable))#<map object at 0x7fc5ab327240> <class 'map'> True
#想要打印map的内容,可以转换为列表打印出来
print(list(map(mypower, [1,2,3])))
#或者通过for循环
for i in m:
print(i)
def fun(*num):
return sum(num)
m = map(fun, [1, 2, 3], {5, 6, 7})
for i in m:
print(i)
通过reduce实现磊加和阶乘
from functools import reduce #调用reduce模块
#累加
def add(x,y):
return x+y
print(reduce(add,range(1,101)))
#阶乘
def e(x,y):
return x*y
print(reduce(e,range(1,6)))
filter:过滤
print([i for i in [12,34,56,67] if i%2==0]) #过滤出列表中的所有偶数
过滤函数的应用
删除1-100之间的质数
#首先找出1-100之间的所有质数
def is_prime(num):
if num <= 0:
return False
elif num == 1 and num ==2:
return True
else:
for i in range(2,num):
if num%i == 0:
return False
else:
return True
#判断这个是不是质数
def is_not_prime(num):
return not is_prime(num)
#利用高阶函数过滤
print(list(filter(is_not_prime,range(1,101))))
sorted排序
用sort函数对列表排序时会影响列表本身,而sorted不会。
print(sorted([235,23,25,333])) #由小到大
print(sorted([235,23,25,333],reverse=True)) #反转由大到小
info = [
['001', 'apple', 1000, 2],
['002', 'xiaomi', 10, 2000],
['003', 'Oppo', 200, 1900],
['004', 'computer', 900, 5000]
]
#按price排序
def sorted_by_prince(info):
return info[3]
print(sorted(info,key=sorted_by_prince))
info = {
'001':{
'name':'apple',
'count':1000,
'price':2
},
'002': {
'name': 'xiaomi',
'count': 10,
'price': 2000
},
'003': {
'name': 'Oppo',
'count': 200,
'price': 1900
}
}
def sorted_by_price(num):
return num['price']
print(sorted(info.values(),key=sorted_by_price))
print(sorted(info.values(),key=lambda num:num['price']))
sorted函数的应用,移动数组中的0,或者其他元素
n = int(input())
l = [int(input()) for i in range(n)]
def sort_by(num):
if num == 0:
return 1
else:
return 0
print(sorted(l,key=sort_by)) #将'0'放在最后
print(sorted(l,key=lambda num : 0 if num==0 else 1))#将0放在最前面
高阶函数的返回值是函数
闭包:函数里面嵌套函数,可以用于函数装饰器
def compare1(base): # base=10
def compare2(y): # y = 3
return base > y
return compare2
装饰器
装饰器的第一种模版
import functools
def 装置启名称(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
pass
return wrapper
#使用装饰器 语法糖
@装饰器名称 #hello = 装饰器名称 hello = wrapper
def hello():
pass
hello() #实质上是执行wrapper函数
装饰器的应用
计算一个函数的执行时间
import time
def compute_time(fun):
# @functools.wraps(fun)
def wrapper():
start_time = time.time()
fun()
end_time = time.time()
print("%S函数执行的时间%ss",(fun.__name__,end_time-start_time))
return wrapper
@compute_time
def hello():
print("hello")
time.sleep(1)
hello()
实现日志记录的装饰器
import functools
import time
import random
def info_log(fun):
@functools.wraps(fun)
def wrapper(*args): #*args,**kwargs代表可变参数和关键字参数,
"""
this is a wrapper function add log
"""
start_time = time.time()
res = fun(*args) #*args,*kwargs代表对元组和字典进行解包
end_time = time.time()
print("%s %s 执行时间为%.2fs 执行结果%s" %(time.ctime(),fun.__name__,end_time-start_time,res))
return res
return wrapper
@info_log
def log(x,y):
"""
add function
:param x: num1 -> int
:param y: num2 -> int
:return: num1+num2 -> int
"""
time.sleep(random.random()) #随机生成一个0-1的数
return x+y
log(1,2)
print(log.__name__)#打印函数名称
print(log.__doc__) #打印函数功能
装饰器的第二个模版
def decorator_a(func):
def inner_a(*args, **kwargs):
print('Get in inner_a')
return func(*args, **kwargs) # f(1)
return inner_a
def decorator_b(func): # decorator_b(inner_a)
def inner_b(*args, **kwargs):
print('Get in inner_b')
return func(*args, **kwargs) # inner_a(1)
return inner_b
# 当有多个装饰器时, 从下到上调用装饰器;
@decorator_b # f = decorator_b(inner_a) # f=inner_b
@decorator_a # f = decorator_a(f) f=inner_a
def f(x):
print('Get in f')
return x * 2
f(1)
在实际应用中,会使用多个装饰器,先判断是否登录成功,再判断权限是否够
import functools
def is_admin(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
if kwargs['name']=='admin':
fun(*args,**kwargs)
else:
print("no permission")
return wrapper
login = ['root','westos','admin']
def is_login(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
if kwargs['name'] in login:
fun(*args,**kwargs)
else:
print("%s没有登录" %(kwargs['name']))
return wrapper
@is_login
@is_admin
def bbs(name):
print("bbs...")
bbs(name='admin')
匿名函数lambda
#利用匿名函数求1-100之间所有偶数的和
from functools import reduce
print(reduce(lambda x,y:x+y,range(2,101,2)))