*********函数*********
1).函数的定义和使用
定义函数, 并不会执行;
***无参数的函数***
#定义函数
def hello():
# 函数体
print("hello")
# 调用函数
hello()
***带参数的函数***
(定义函数函数名后的参数是形式参数,调用函数时添加的是实际参数)
def fun1(name):
# name = "fentiao"
# 定义函数时的变量称为形式参数, 变量名可以任意起;
print("hello %s" %(name))
fun1("fentiao")
2).函数额的返回值
# 函数调用时一般有返回值;没有返回值时, python中默认返回None;
def hello():
print("hello")
res = hello()
print(res)
def fun(a): # a = [1, 2, 3, 4, 5]
# 接收一个列表, 求这个列表的最大值,平均值, 最小值;
max_num = max(a)
min_num = min(a)
avg_num = sum(a)/len(a)
# python函数中, 只能返回一个值;
# 如果要返回多个值, 会把返回的值封装为一个元组数据类型;
return max_num, avg_num, min_num
variables = fun([1, 2, 3, 4, 5])
print(variables, type(variables))
3.)函数中形参的类型
***必选参数***
def add(x, y, z): # x=1, y=2
return x + y + z
print(add(2,3,4))
***默认参数***
def mypow(x, y=2):
return x ** y
print(mypow(2))
print(mypow(2, 3))
***可变参数***
# *args, args实质是一个元组;
def mySum(*args):
print(args, type(args))
return sum(args)
print(mySum(1,2,3,4,5))
***关键字参数***
# 关键字参数**kwargs<生成字典>
def func(label,value,**kwargs):
str1=''
for key, valu in kwargs.items():
str1+='%s+%s'%(key,valu)
return '<%s %s>%s</%s>'%(label,str1,value,label)
print(func('dict','网页',id='s.sdj',height=100,width=100))
注:定义函数时, 默认参数的默认值尽量不是可变参数
参数顺序:必选,> 默认,> 可变,> 关键字
4).函数的作用域
num = 10
print("out fun: id=", id(num))
def fun():
# 局部作用域, 在函数运行时生效, 函数运行结束则释放;
num = 2#当函数执行结束, 变量num的值2被释放掉
print("in fun: id=", id(num))
print("in fun: num = %s" %(num))
fun()
print("out fun: num =%s" %(num))
***global关键字***
num = 10
def fun():
# 通过global关键字声明局部变量为全局变量, 让函数执行完, 2依旧生效;
global num
num = 2
fun()
print(num)
5).函数的练习
题目需求:
对于一个十进制的正整数, 定义f(n)为其各位数字的平方和,如:
f(13) = 1**2 + 3**2 = 10
f(207) = 2**2 + 0**2 + 7**2 = 53
下面给出三个正整数k,a, b,你需要计算有多少个正整数n满足a<=n<=b,
且k*f(n)=n
输入:
第一行包含3个正整数k,a, b, k>=1, a,b<=10**18, a<=b;
输出:
输出对应的答案;
范例:
输入: 51 5000 10000
输出: 3
def fn(n):
a = 0
for i in str(n):
a += int(i) ** 2
return a
def isok(k, n):
if k * fn(n) == n:
return 0
else:
return 1
def main(k, a, b):
count = 0
for n in range(a, b + 1):
if isok(k, n) == 0:
count += 1
return count
print(main(51, 5000, 10000))
注:
是否可以进行迭代的判断:
from collections import Iterable#导入模块(Iterable可迭代的)
isinstance(1, int)
print(isinstance(1,Iterable))
print(isinstance({1,2,3},Iterable))
*********生成式*********
***列表生成式***
li = ['frdgrfgdsHHJJ', 'cdsfregHHHJDGF']
print([i.lower() for i in li])
***字典生成式***
#大小写key值合并, 统一以小写key值输出;
d = dict(a=2, b=1, c=2, B=9, A=5)
print({k.lower():d.get(k.lower(),0)+d.get(k.upper(),0) for k in d})
***集合生成式***
print({i ** 2 for i in {1, 2, 3, 9, 12} if i % 3 == 0})
*********生成器*********
#列表生成式
# 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.x中g.next() 通用的方式:next(g)
for 循环查看
def gen():
while True:
try:
yield 'a'
except TypeError:
print('type error')
# throw方法:给生成器发送一个异常(错误); 但是不影响g.__next__()的执行;
# close(): 关闭生成器, 再次执行g.__next__()报错;
g = gen()
print(g.__next__())
g.throw(TypeError)
print(g.__next__())
当在函数中看到yield关键字, 那么这个函数调用的返回值是一个生成器
def fib(num):
a, b, count = 0, 1, 1 # 0, 1
while count <= num:
yield b
a, b = b, a + b #a=2, b=3
count += 1
g = fib(10)
for i in g:
print(i)
yield的用法及<生产者消费者模型>
import time
import random
def comsumer(name):
print('%s准备买包子'%name)
while 1:
kind=yield
print('%s已经购买了%s味的包子'%(name,kind))
def producer(name):
a=comsumer('张龙')
b=comsumer('少鹏')
a.__next__()
b.__next__()
print('厨师%s正在制作包子'%name)
for kind in ['微辣','中辣','特辣']:
time.sleep(random.randint(1,2))
print('厨师%s已经制做好了%s味的包子'%(name,kind))
a.send(kind)
b.send(kind)
producer('王浪')
*********高阶函数*********
***map函数***
#map(fun,Iterable)对可迭代对象依次执行fun函数
# 需求: 用户接收一串数字; '1 3 5 7 8', 将该字符串中的所有数字转化为整形,并以列表格式输出;
s = '1 3 5 7 8'
print(list(map(int, s.split())))
***reduce函数***
reduce在python2中可以使用,在python3.x不是内置高阶函数, 而是需要导入from functools import reduce;
# 需求: 用户输入数字n; 求n的阶乘; 5!= 1*2*3*4*5
from functools import reduce
def func(x,y):
return x*y
print(reduce(func, range(1,6))) # func(func(1,2),3)
***filter函数***
#filter(func, iterable),只有一个形参, 函数的返回值只能是True或者False
def isodd(num):
if num %2 == 0:
return True
else:
return False
print(list(filter(isodd, range(10))))
***sorted函数***
# 排序: 由大到小
print(sorted([23,56546,78]))
# 排序: 由小到大, reverse=True, 代表排序后进行反转;
print(sorted([23,56546,78], reverse=True))
info = [
['001', 'apple', 1000, 2],
['002', 'xiaomi', 10, 2000],
['003', 'Oppo', 200, 1900],
['004', 'computer', 900, 5000]
]
def sorted_by_count(item):
return item[2]
print(sorted(info, key=sorted_by_count))
另外:匿名函数(简化普通函数/匿名函数的关键字为 lambda, 冒号前面是形式参数, 冒号后面是返回值)
eg:
f = lambda : "hello"
print(f())
f1 = lambda x, y=2: x**y
print(f1(2))
print(f1(2,3))
f2 = lambda *args: sum(args)
print(f2(1,2,3,4,5))
*********装饰器*********
装饰器应用场景: 如果你想在执行函数之前做什么或者执行函数之后做什么, 建议使用装饰器;
模板:
import functools
def add_info(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
# 函数执行之前做的操作
res = fun(*args, **kwargs)
# 函数执行之前做的操作
return res
return wrapper
练习1:
def admin(fun):
def wrapper(*args,**kwargs):
if kwargs.get('name')=='root':
fun(*args,**kwargs)
else:
print('不是管理员,没有权限添加学生信息!')
return wrapper
@admin
def add_student(name='root'):
print('***添加学生信息***')
add_student(name='student')
练习2:
# def addii(i):
# def pp():
# print('新年快乐!\n欢迎来到ICBC!')
# i()
# return pp
#
# @addii
# def savemoney():
# print('存钱......')
# savemoney()