一、函数
函数,就是把具有独立功能的代码块组织成为一个小模块,在需要的时候调用
在python中函数是以def定义
def hello():
print('hello1')
print('hello2')
print('hello3') ## 定义函数
hello() ## 调用函数
函数的嵌套
一个函数内嵌套另一个函数,被嵌套的函数也需要调用
def hello():
print('hello')
def python():
print('python')
python()
hello()
函数的形参和实参
def定义函数的时候所用的变量 叫形参,可任意起名
调用函数时真实的数据信息,传递的参数 叫实参
例:
def welcome(x): ## x 可以为任意字符,是形参
print('hello',x)
welcome(westos) ## westos为传递给函数的真实数据,实参
函数形参的四大参数
形参:位置参数 默认参数 可变参数 关键字参数
1.位置参数:形参和实参个数 位置必须保持一致
def getInfo(name,age):
print('Name:%s,Age:%s' %(name,age))
getInfo('Tom',18)
getInfo(18,'Tom') ##形参只是表示变量,调用函数依靠与实参的数据
例:按照函数显示应该是名字为tom,年龄为18。但是调用函数时,实参数据的传送才是最后函数调用结果的依据。如图18 和 tom交换位置,函数就会变成名字为18 , 年龄为tom
如果想实参的先后顺序不影响函数的正常使用,可以指定形参对应实参
getInfo(age=18,name='Tom')
2.默认参数: 形参和实参可以不一致,如果没有传递值,用默认值
def mypow(x,y=2): ##在定义函数的时候为形参设置一个默认值
print(x**y)
mypow(4) ## 如果没有输入实参去调用相应的形参,将会使用默认值
mypow(2,4) ## 如果有实参去调用相应的形参,将不会使用默认值
3.可变参数:传入的实参可变
例如:在求和运算中,不确定需要被求和的实参有多少个,形参使用可变参数就能解决这一问题
def mysum(*a): ## *a为可变参数,a为元组类型
sum = 0
for item in a:
sum += item
print(sum)
mysum(1,2,3,4,5,6)
4.关键字参数
定义函数的时候不确定会有多少个实参来调用函数
**kwargs —> 是一个字典,可以传递任意个key-value值
def getStuInfo(name,age,**kwargs):
print(name,age)
print(kwargs,type(kwargs)) ##打印kwargs,并查看类型
return name,age,kwargs # 返回值
a = getStuInfo('westos','20',gender='male',hobbies=['coding','running'])
print(a)
运行之后可以看到,kwargs为dict类型,并且成功打印出来了实参调用函数的数据
函数的返回值
返回值:函数运算的结果,当还需要进一步操作时,用return来返回
函数的执行结果,如果没有返回值,默认为None
一旦遇到return,函数执行结束,后面的代码不会执行
以上一个实验为例:
def getStuInfo(name,age,**kwargs):
print(name,age)
print(kwargs,type(kwargs)) ##打印kwargs,并查看类型
#return name,age,kwargs
## 注释掉返回值,将无法打印函数执行结果,并返回none
a = getStuInfo('westos','20',gender='male',hobbies=['coding','running'])
print(a)
变量的作用域
局部变量和全局变量
局部变量 是在函数内部定义的变量,只能在函数内部使用
全局变量 是在函数外部定义的变量,(没有定义在某一个函数内),所有函数内部都可以使用这个变量
局部变量:
分别定义demo1内的num为局部变量,只能在demo1函数使用,其他函数无法使用
函数demo2无法调用函数demo1的局部变量num所以产生报错。
全局变量:
使用global声明之后,num变为全局变量,另一个函数demo2也能使用
二、列表生成式
列表生成式 会将所有的结果全部计算出来,把结果存放到内存中,如果列表中数据比较多,就会占用过多的内存空间,可能会导致MemoryError内存错误或者导致程序在运行时出现卡顿的情况。
例:
在数字0-99中,取大于50的数,分为拼接在apple字符串后面,并存到一个列表中
一般的正常写法:
messi = []
for i in range(100):
if i > 50:
messi.append("apple%s" % i)
print(messi)
使用列表生成式的写法:
l = ["apple%s" % i for i in range(100) if i > 50]
## 把所有的条件写入一行,与常规写法一样的结果
print(l)
三、字典生成式
定义:
同列表生成式一样,字典生成式是用来快速生成字典的。通过直接使用一句代码来指定要生成字典的条件及内容,替换了使用多行条件或者是多行循环代码的传统方式。
格式:
{字典内容+循环条件+判断条件【产生条件】}
例:大小写key的值和并,统一以小写输出
常规写法:
d = dict(a=2,b=1,c=2,B=9,A=10)
new_d = {}
for k,v in d.items():
low_k = k.lower()
if low_k not in new_d:
new_d[low_k] = v
else:
new_d[low_k] += v
print(new_d)
字典生成式写法:
print({k.lower(): d.get(k.lower(),0) + d.get(k.upper(),0)
for k in d})
生成式变式
例:
li = [
[1,2,3],
[4,5,6],
[7,8,9]
]
以【1,2,3,4……】的形式显示li的内容
常规写法:
result = []
for i in li: ## i循环的是 [1,2,3],[4,5,6],[7,8,9]
for j in i: ##j循环的是1,2,3……
result.append(j)
print(result,type(result))
使用生成式的写法:
print([j for i in li for j in i])
使用生成式变式的写法
四、高阶函数
高阶函数:
实参是一个函数名
函数的返回值是一个函数
在数学上的写法为 f(g(x))
例:
f = abs ##函数本身也可以赋值给变量,变量可以指向函数
print(f(-10))
## abs是求绝对值,比如print(abs(-11))出来的是11
传递的参数包括函数名
def fun(x,y,f):
return f(x),f(y)
print(fun(-11,10,abs))
内置高阶函数map
map()函数接收两个参数,一个是函数,一个是序列
map将传入的函数依次作用到序列的每个元素,并把结果作为新的序列返回
例:
序列[-1,2,-3,4]的每个元素求绝对值
print(list(map(abs,[-1,2,-3,4])))
内置高阶函数reduce
reduce:接收两个参数,把一个函数作用在一个序列上,reduce会把结果继续和序列的下一个元素做累积计算
python3中reduce函数需要从functools中导入
例:求range(1,5)的阶乘。即 123*4
from functools import reduce
def multi(x,y):
return x*y
print(reduce(multi,range(1,5)))
高阶函数filter
filter过滤函数:接收一个函数和一个序列
filter函数把传入的函数依次作用于每个元素,然后根据返回值是True还是False来决定保留或者丢弃该元素
例:
用列表列出10以内的偶数
def isodd(num):
if num % 2 == 0:
return True
else:
return False
print(list(filter(isodd,range(10))))
内置高阶函数sorted
sorted函数用于排序
li = [2,1,3,4]
li.sort(reverse=True) ##从大到小的排序
print(li)
a = sorted(li) ## 从小到大的排序
print(a)
匿名函数
python 使用 lambda 来创建匿名函数。
lambda这个名称来自于LISP,而LISP则是从lambda calculus(一种符号逻辑形式)取这个名称的。
在Python中,lambda作为一个关键字,作为引入表达式的语法。想比较def函数,lambda是单一的表达式,而不是语句块.
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
匿名函数的关键字为lambda,冒号前面是形参,冒号后面是返回值。
例:对字典排序
infors = [{"name":"Tom","age":12},
{"name":"Lily","age":20},
{"name":"Jack","age":10}]
infors.sort(key=lambda x:x['age']) ## 根据age对字典排序
print(infors)