一、匿名函数
匿名函数本质还是函数,之前函数的所有内容都适用于它
1,匿名函数的声明
函数名=lambda 参数列表:返回值
2,说明:
函数名:变量名
lambda:关键字
参数列表:参数名1,参数名2,........
冒号:固定写法
返回值:表达式,表达式的值就是返回值
3,调用
匿名函数的调用和普通函数一样
函数名(实参列表)
写一个匿名函数,计算两个数的和
# 声明一个匿名函数
my_sum=lambda x,y:x+y
# 调用函数
print(my_sum(10,20)) #30
# 下面这个函数和上面等同
def my_sum(x,y):
return x+y
练习1:写一个匿名函数,获取指定数字列表,指定下标的值的1/2
a=[1,2,3,4,5,6,7,8]
half_list=lambda list1,index1=5:list1[index1]/2
# 位置参数
print(half_list(a,4)) #2.5
print(half_list(a)) #3.0
# 关键字参数
print(half_list(list1=[1,3,5,7,9],index1=4)) #4.5
练习2:写一个匿名函数,获取指定数字列表的所有元素和及平均值
a=[1,2,3,4,5,6,7,8]
sum_aver=lambda list2:(sum(list2),sum(list2)/len(list2))
sum1,average=sum_aver(a)
print(sum_aver(a)) #(36, 4.5)
print(sum1) #36
print(average) #4.5
补充,python中的函数可以有多个返回值。就是在一个return后返回多个值,多个值之间用逗号隔开
def sum_aver1(list):
return sum(list),sum(list)/len(list)
print(sum_aver1(a)) #(36, 4.5)-------最终是将返回值放到一个元祖中返回的
二、变量的作用域
1,函数的调用过程是一个压栈的过程:
- 每次调用一个函数,系统就会在内存区域中的栈区间去开辟空间,保存函数调用过程中产生的数据,当函数调用完成后,对应的栈区间会自动销毁。
- 函数调用时产生的栈区间中保存的数据有:形参、在函数中声明的变量
def func1(a,b):
c=100
print(a,b,c)
func1(20,30)
2,什么是作用域:
指的就是一个变量能够使用的范围
3,全局变量和局部变量
3.1、全局变量:声明在函数和类的外面的变量都是全局变量。
全局变量的作用域:从声明开始到文件结束,任何地方都可以使用
a=100 #全局变量
if a>10:
b=20 #全局变量
for x in range(10):
print(x) #x也是全局变量
3.2、局部变量:声明在函数和类中的变量是局部变量。
局部变量的作用域:从声明开始到函数结束或者是类结束
注意:函数的参数是声明在函数中的局部变量
# x,y,z都是局部变量
def func3(x1,y1):
z1='abc'
print(x1,y1,z1)
func3('a','b')
# 局部变量只能在声明的函数中使用,不能在函数外面使用
# print(x1)--------NameError: name 'x1' is not defined
3.3、global关键字:是在函数中声明一个全局变量
global 变量名
变量名=值
# 全局变量
num1=100
def func4():
num1=200
print(num1)
#如果全局变量和局部变量同名,那局部变量的作用域内使用的是局部变量的值
# 想要在局部区域内修改全局变量的值
global num2 #说明从这句开始后面的num2都是全局变量
num2=180
print(num2)
func4()
print(num1) -----------100---全局变量
print(num2)-------------180---全局变量
3.4.nonlocal 不声明局部变量
def func5():
#局部变量
nn=10
#函数中可以声明函数
def func6():
nonlocal nn #在局部的局部中修改局部变量的值
nn=20
print('func6',nn) #func6 20
func6()
print('func5', nn) #func5 10 / 20(有nonlocal)
func5()
1,练习
def func():
a=[]
for i in range(5):
a.append(lambda x:x*i)
return a
aa=func()
print(aa)
print(aa[0](2),aa[2](2),aa[3](2)) #8 8 8
三、递归函数
1,什么是递归函数
就是在函数的函数体中调用函数本身,这样的函数就是递归函数
2,while循环能做的事情,递归都可以做
这儿的func1就是递归函数
def func1():
print('aaa')
func1()
3,怎么写递归函数
第一步:找临界值(找到让循环结束的值/找到能够确定函数结果值)
第二步:假设函数功能已经实现的前提下,找关系(找f(n)和f(n-1)/当次循环和上次循环的关系)
第三步:根据f(n)和f(n-1)的关系,来通过f(n-1)实现f(n)的效果
1+2+3+4+5....+100
sum1=0
for x in range(101):
sum1+=x
print(sum1)
用递归函数实现
def my_sum(n):
# 1,找临界值(在临界值的位置让函数结束)
if n==1:
return 1
#2,找关系
'''
my_sum(n):1+2+3+...+n
my_sum(n-1):1+2+3+...+n-1
my_sum(n)=my_sum(n-1)+n
'''
#3,使用f(n-1)实现f(n)
return my_sum(n-1)+n
print(my_sum(100))
运行过程
return my_sum(n-1)+n
my_sum(100) n=100 return my_sum(99)+100
my_sum(99) n=99 return my_sum(98)+99
.......
my_sum(1) n=1 return my_sum(0)+1
my_sum(0) n=0 return 0
练习,是用递归函数计算斐波那契数列1,1,2,3,5....第n个数
def feibo(n):
if n==1 or n==2:
return 1
a=feibo(n - 2) + feibo(n - 1)
return a
print(feibo(6))
运行过程
feibo(n - 2) + feibo(n - 1)
feibo(n) n=6 return feibo(4) + feibo(5)
feibo(n) n=5 return feibo(3) + feibo(4)
feibo(n) n=4 return feibo(2) + feibo(3)
feibo(n) n=3 return feibo(1) + feibo(2)
feibo(n) n=2 return 1
feibo(n) n=6 return 1
练习:使用递归完成以下效果
n=3
***
**
*
n=5
*****
****
***
**
*
代码
def func2(n):
if n==1:
print('*')
return #临界值的地方让函数结束
print('*'*n)
func2(n-1)
return 2
print(func2(5))
4,在实际开发中,递归能不用就不用
递归需要不断调用函数,开辟空间,消耗内存
四、模块和包的使用
1封装:
1.1,函数:对实现某一特定功能的代码段的封装
1.2, 模块(一个py文件就是一个模块):对变量,函数,类进行封装
my_list---自定义模块
empty=[]
def count(list1,item):
count=0
for x in list1:
if x==item:
count+=1
return count
print('!!',1,1,1,1,1,1,1)
if __name__ == '__main__':
print(1, 1, 1, 1, 1, 1, 1)
2,怎么使用其他模块中的内容
2.1.(import 模块)
通过模块.内容的形式去使用模块中的内容(能够使用的是全局变量,函数,类)
1)导入模块
import math #导入系统的math模块
import my_list #导入自定的my_list模块
2)使用模块内容
# a,使用模块中的全局变量
print(my_list.empty)
# b.使用模块中的函数
number=my_list.count([1,2,3,4,5,6,7,8,9,1],1)
print(number)
2.2.(from 模块 import 模块中的内容)
可以直接使用模块中的内容(可以同时导入多个内容,相互之间用逗号隔开)
from my_list import count,empty
print(count([1,2,3,4,5,6],1))
print(empty)
2.3、(from 模块 import *)----将模块中的所有的内容都导入
from math import *
print(pi)
print(sqrt(4))
3,重命名
import 模块 as新名字
from 模块 import 内容 as 新名字
--------import 模块 as新名字
import random as RAN
print(RAN.randint(1,5))
--------from 模块 import 内容 as 新名字
from datetime import date as dateclass,time as timeclass
4 导入模块会有其它代码运行
将不希望被别的模块导入的代码放到模块的这个if语句中
if name == 'main':
-
每个模块都有一个“name ”属性,这个属性的值默认就是当前模块的文件名。
-
当当前模块正在被执行(直接在当前模块中点了run)的时候 name属性的值是'main' 。
-
建议:函数的声明、类的声明一般写在if的外面,其他的写在if里面。(想要被外部使用的全局变量也可以写在外面)
网友评论