目录
1.函数的参数
在python中函数参数的定义方式有一下4中方式。
1)位置参数
2)关键字参数:
3)默认参数:
4)可变参数(*args,**kwargs):
1.1 位置参数
在我们在传参的时候,实参传递的顺序按照形参定义的顺序进行传递的传参方式。
实参和形参位置一一对应
def sum(num1,num2):
print(num1+num2)
sum(1,2)
1.2 关键字参数
我们在传参的时候,以形参等于实参的形式忽略形参定义的顺序进行传参的传参方式。
def sum(num1,num2):
print(num1)
print(num2)
print(num1+num2)
sum(num2 = 2,num1 = 4)
关键字参数和位置参数同时使用:
关键字参数必须在位置参数后面定义。
def sum(num1,num2):
print(num1)
print(num2)
print(num1+num2)
sum(2,num2 = 4)
1.3 默认参数
是在我们定义参数时候,我们给形参一个默认值,在我们调用函数的时候,如果不给有默认值的形参传参,会自动采用默认值。
当某个值变化小的时候,我们就可以使用默认参数。
def user_xx(name,age,gender = '男'):
print('姓名:{},年龄:{},性别:{}'.format(name,age,gender))
user_xx('赵四',23)
user_xx('翠花',21,'女')
#输出:
#姓名:赵四,年龄:23,性别:男
#姓名:翠花,年龄:21,性别:女
注意:
函数定义的时候,默认参数、位置参数同时使用的时候,默认参数必须放在位置参数的后面
函数参数顺序:
位置参数、*args、默认参数、**kwargs
def func(a,*args,b =12,**kwargs):
print(a) #输出--->zs
print(args) #输出--->('cc',)
print(b) #输出--->s
print(kwargs) #输出--->{'c': 3214}
func('zs','cc',b='s',c = 3214)
1.4 可变参数
如果函数中的参数过多,我们定义起来非常的麻烦,调用起来也非常的麻烦,因此python给我们提供了可变参数类型。能处理比当初声明时更多的参数,会将传入的参数变成元组(*args)或者字典(**kwargs)
(1)元组参数 *args
通过给形参前面添加*使参数变成一个元组,所有传递的参数变成元组的元素
注意: args参数名称可以任意命名,但是一般我们叫他 args。
def func(*aa):
print(aa) #输出--->(1, 32, 4, 325, 43)
print(aa[0], aa[1]) #输出--->1 32
func(1, 32, 4, 325, 43)
* 具有打散序列的功能:
tup = (1, 2, 3, 4)
print(*tup) #输出--->1 2 3 4
lst = ['1', 'a', 98]
print(*lst) #输出--->1 a 98
def func(a,b,c):
print(a,b,c)
tup = (1,2,32)
func(*tup) #输出--->1 2 32
(2)字典参数 **kwargs
通过给形参前面添加**使参数变成一个字典,所有传递的参数变成字典的键值对,这里传参要求键等于值的形式。
**kwargs结果类型是字典,传递值是以key=value方式传入
def func(**kwargs):
print(kwargs) #{'name': 'zs', 'age': 18, 'tell': 121243}
#func(1,2,3) #报错,kwargs只能接受关键字参数
func(name = 'zs',age = 18,tell = 121243)
** 具有打散字典的功能
def func(name,age):
print(name,age)
dic = {'name':'张三','age':10}
func(**dic) #输出--->张三 10
注意事项:**kwargs必须放在*args后面。
函数参数总结:
定义函数时参数的顺序: 位置参数,元组参数,默认参数,字典参数。
2.函数的嵌套
在函数内部调用其他函数
def fun1():
print('11111')
def fun2():
print('22222')
fun1() #输出--->11111 不执行fun2的函数体
综合案例:
def fun1():
print('11111')
def fun2():
print('22222')
fun1()
def fun1():
print('fun1....')
def fun2():
fun1()
print('fun2....')
def fun3():
fun2()
print('fun3....')
fun3()
#输出结果:
'''
fun1...
fun2...
fun3...
'''
3.命名空间
Python的命名空间的本质是一个字典,用来记录变量名称和值。字典的key是变量的名称,字典的value对于的是变量的值。
例如 {‘name’:’zs’,’age’:10}
命名空间一共分为三种:局部命名空间、全局命名空间、内置命名空间
(1)局部空间:
每个函数都有自己的命名空间,叫做局部空间,它记录了函数的变量,包括函数的参数 和局部定义的变量
(2)全局空间:
每个模块拥有它自已的命名空间,叫做全局命名空间,它记录了模块的变量,包括函数、 类、其它导入的模块。
(3)内置名称空间:
任何模块均可访问它,它存放着内置的函数和异常。
input,print,str,list,tuple...
3.1名称空间的访问
局部名称空间使用 locals() 函数来访问
全局命名空间的访问使用globals()函数访问。
局部命名空间、 全局命名空间:
def func(c):
a = 1
b = 5
ret = locals()
print(ret) # 局部命名空间{'b': 5, 'a': 1, 'c': 30}
func(30)
ret = globals()
print(ret) #获取全局变量 输出{'__name__': '__main__', '__doc__': ...}很多内置变量的名称
3.2命名空间的加载顺序
内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)当函数返回结果 或 抛出异常时,被删除。每一个递归调用的函数都拥有自己的命名空间。
3.3命名空间的查找顺序
当使用某个变量的时候,先从局部命名空间中找,如果能找到则停止搜索,如果找不到在去全局名称空间中查找,如果找到则停止搜索,如果找不到则到内置名称空间中查找,如果找不到则报错。
嵌套函数的情况:
1、先在当前 (嵌套的或 lambda) 函数的命名空间中搜索
2、然后是在父函数的命名空间中搜索
3、接着是模块命名空间中搜索
4、最后在内置命名空间中搜索
注意:自己的变量名称不要和内置变量名称相同,否则不能使用内置中同名的方法
4.作用域
作用域指的是变量在程序中的可应用范围。
作用域按照变量的定义位置可以划分为4类即LEGB:
Local(函数内部)局部作用域。
Enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)。
Global(模块全局)全局作用域。
Built-in(内建)内建作用域。
Python搜索4个作用域[本地作用域(L)之后是上一层结构中def或者lambda的本地作用域(E),之后是全局作用域(G)最后是内置作用域(B)(即python的内置类和函数等)]
并且在第一处能够找到这个变量名的地方停下来。如果变量名在整个的搜索过程中都没有找到,Python就会报错。
注意:
在python中,模块(module),类(class)、函数(def、lambda)会产生新的作用域,其他代码块是不会产生作用域的,也就是说,类似条件判断(if…..else)、循环语句(for x in data)、异常捕捉(try…catch)等的变量是可以全局使用的。
5.全局变量和局部变量
在函数中定义的变量称为局部变量,只在函数内部生效,
在程序一开始定义的变量称为全局变量,全局变量的作用域是整个程序。
输出: ls
全局变量是不可变数据类型,函数无法修改全局变量的值
a = 1
def func(b):
b = 2
print(b) # 2
func(a)
print(a) # 1
全局变量是可变数据类型,函数可以修改全局变量的值
a = [1, 2, 3, 4]
def func(b):
b.append(65)
print(b) #[1,2,3,4,65]
func(a)
print(a) #[1,2,3,4,65]
6.global和nonlocal关键字
global关键字可以将局部变量变成一个全局变量。
格式: global 变量名称
a = 10
print(id(a))
def func():
global a #申明a为全局变量a
# print(id(a)) #id相同
a = 20 #修改a的值 开辟新空间
print(a) #输出 20
func()
print(a) #输出 20
nonlocal关键字可以修改外层(非全局)变量。
def outter():
name = 'zs'
print(id(name))
def inner():
nonlocal name # 和outter中是同一变量
print(id(name))
name = '赵四' # 重新开辟空间
print(name) #输出:'赵四'
inner()
print(name) #输出'赵四'
outter()
7.命名空间和作用域的关系
命名空间定义了在某个作用域内变量名和绑定值之间的对应关系,命名空间是键值对的集合,变量名与值是一一对应关系。作用域定义了命名空间中的变量能够在多大范围内起作用。
8.递归函数
如果一个函数在内部调用自身本身,这个函数就是递归函数。
在使用递归时,需要注意以下几点:
(1).自己调用自己。
(2).必须有一个明确的递归结束条件,称为递归出口。
递归函数输出3,2,1:
def print_num(num):
print(num)
if num == 1:
return
num = num - 1
print_num(num)
print('------>')
print_num(3)
'''
输出结果:
3
2
1
------>
------>
'''
递归函数求阶乘:
def jiecheng(num):
if num == 1:
return 1
return num * jiecheng(num - 1)
ret = jiecheng(4)
print(ret)
递归函数查找数字:
def search_num(number, start, end): #number为需要查找的数字,start、end分别为开始结束数字
if number == start:
return start
else:
middle = (start + end) // 2
if middle <= number:
return search_num(number, middle, end)
else:
return search_num(number, start, middle)
ret = search_num(3, 1, 4)
print(ret)
9.内置函数
1.abs()函数
求数字的绝对值
abs() #求绝对值
ret = abs(-10)
print(ret) # 输出--->10
2.max()函数
max(iterable, key, default) 求迭代器的最大值,其中iterable 为迭代器,max会for i in … 遍历一遍这个迭代器,然后将迭代器的每一个返回值当做参数传给key=func 中的func(一般用lambda表达式定义) ,然后将func的执行结果传给key,然后以key为标准进行大小的判断。
#简单使用max()函数
ret = max(1, 23, 44, 32, 12)
print(ret) # 输出--->44
lst = [2, 3, 41, 31]
print(max(lst)) # 输出--->41
lst = [22, -55, 2, 11]
print(max(lst, key=abs)) # 使用key关键字指定比较规则,取绝对值后比较
列表中嵌套字典,根据'price'比较,返回最大值的所有信息
lst = [
{'name': 'zxb', 'price': 35},
{'name': 'wxw', 'price': 55},
{'name': 'lxb', 'price': 30}
]
def max_price(dic):
return dic['price']
ret = max(lst, key=max_price)
print(ret) #输出:{'name': 'wxw', 'price': 55}
3.map()函数
有两个参数,第一个参数是一个函数,第二个参数是可迭代的内容。
函数会依次作用在可迭代内容的每一个元素上进行计算,然后返回一个新的可迭代内容。
求 lst 中每一个元素的平方值:
lst = [1, 3, 4]
def square(num):
num2 = num ** 2
return num2
ret = map(square, lst) #返回一个迭代器
print(ret)
for i in ret:
print(i) #for循环遍历输出迭代器里内容
ret = list(map(square,lst))
print(ret) #转换为列表数据类型,直接输出
4.filter()函数
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进判,
然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def odd_number(num): #定义odd_number方法,返回所有奇数
if num % 2 == 1:
return num
ret = filter(odd_number, lst) #用filter函数,返回以奇数组成的新列表
for i in ret:
print(i)
5.zip()函数
zip函数接受任意多个可迭代对象作为参数,将对象中对应的元素打包成一个tuple,
然后返回一个可迭代的zip对象.这个可迭代对象可以使用循环的方式列出其元素
若多个可迭代对象的长度不一致,则所返回的列表与长度最短的可迭代对象相同。
a = [1, 2, 3]
b = ['a', 'b', 'c']
ret = zip(a, b)
for i in ret:
print(i)
#输出:
(1, 'a')
(2, 'b')
(3, 'c')
tu1 = (('a'), ('b'))
tu2 = (('c'), ('d'))
ret = zip(tu1, tu2)
for i in ret:
print(i)
#输出:
('a', 'c')
('b', 'd')
若多个可迭代对象的长度不一致,则所返回的列表与长度最短的可迭代对象相同
zip() 函数
lst1 = [1,2,3]
lst2 = ['a','b','c','d']
s = zip(lst1,lst2)
for i in s:
print(i)
输出结果:
小练习:
要求: [('a'), ('b')] [('c'), ('d')] ----> [{'a': 'c'}, {'b': 'd'}]
第一种方法:zip()函数
lst = []
tup1 = [('a'), ('b')]
tup2 = [('c'), ('d')]
s = zip(tup1, tup2)
print(s) # 输出结果:('a', 'c')('b', 'd')
第二种方法: map()函数
def func(tup): # 该函数返回两个字典
return {tup[0]: tup[1]}
tup1 = [('a'), ('b')]
tup2 = [('c'), ('d')]
ret = map(func, s)
for i in ret:
print(i)
lst.append(i)
print(lst)