Python函数

函数

可以理解为编程方面的函数是一段可重复使用的代码片段
普通函数是有名字的
python中的lambda表达式可以看做是匿名函数

定义并调用一个简单的函数

def A():        # 定义函数的名字,形参列表
    print("A")      # 函数体
    return 'A'      # 返回值

A() # 调用函数(没有传实参)

执行顺序

  1. A()
  2. def A()
  3. print(“A”)

将执行的函数赋值给变量,变量就能够拿到函数的返回值
如果打印函数名的话 会显示函数对象的内存地址

<function A at 0x0000015B4D582EA0>

函数的好处
- 代码重用
- 容易维护
- 可扩展性强

函数形参&局部变量

def add(a,b):       # a和b就是这个函数的形参
    return a+b

形参的作用是接收函数调用时传入的实参的值(默认情况下实参要和形参一一对应)

局部变量是定义在函数内部的变量
只能在函数体内使用,外部无法使用
形参也属于局部变量

函数内部是可以调用函数外部的变量的
如果函数内找不到变量的话 就会在函数外边找

在python中传递参数时,传递的是引用,这个可以通过id来测输出

a = 1

def a_id(a):
    return id(a)


if id(a) == a_id(a):
    print("是引用,不是复制值")
else:
    print("不是引用")
# 运行结果 是引用

globals & nonlocal

如果想要在函数外部使用函数内的变量的话
可以在该变量前面添加globals关键字
虽然可以在函数外部或者其他函数内部进行调用
但是,开发中并不推荐使用全局变量

a = 1

def A():
    globals a
    a = 2

print(a)    #1
A() # 执行A() 相当于把全局变量a的值改成了2
print(a)    #2

一般来说 变量命名规范
- 全局/常量 都大写
- 局部变量 标识符命名规则

python中还有一个 nonlocal 关键字

def outer():
    def a():
        nonlocal a
        a = 1
        print(a)

    def b():
        print(a)

    def c():
        a()
        b()

    c()


outer()

# 运行结果
# 1
# 1

内层函数中 变量声明为非局部变量
可以理解为介于全局变量和局部变量之间的变量
外层函数的内部都可以随意调用非局部变量
函数外层函数的外部是无法调用非局部变量的

python中形参可以设置默认的值,这个也叫缺省参数
这样即使在调用的时候不给设置默认值的形参传实参也不会报错

def add(a=1,b=2):
    return a+b

print(add())        # 3

默认情况下 调用函数时传入的实参要和定义函数时的形参一一对应
形参有默认值的情况下可以不传值

函数参数

python中有三种参数
1. 普通参数
2. 默认参数
3. 可变参数

普通参数就是一个函数中的局部变量,用于接收函数在调用时传入的实参,普通参数要和实参一一对应(普通参数也叫位置参数)

默认参数是普通参数赋默认值(比如a=None,b=None) 有默认参数的情况下,实参可以不传

可变参数 可以传多个实参,也可以不传,详情如下

实参的关键字参数

def println(a, b, c):
    print(a, b, c)


println(b=2, a=1, c=20)     # 1 2 20

使用关键字参数的点

  • 不再需要考虑参数的顺序,函数的使用将更加容易
  • 可以只对那些我们希望赋予的参数以赋值,只要其它的参数都具有默认参数值。

还有 普通参数要在关键字参数的左边

可变参数

*形参名 表示实参可以传入任意数量的值[比如 func(1,2,3)]
**形参名 表示实参可以传入任意数量的键值对[比如 func(a=1,b=2)]

def func(*args, **kwargs):
    list1 = []
    dict1 = {}

    for i in args:
        list1.append(i)

    for k, v in kwargs.items():
        dict1[k] = v

    print(list1)
    print(dict1)
    print(type(args))
    print(type(kwargs))


func(1, 2, 3, 4, a=1, b=2, c=3)

# 运行结果
[1, 2, 3, 4]
{'a': 1, 'b': 2, 'c': 3}
<class 'tuple'>
<class 'dict'>

如果觉得一个一个写实参的话比较费劲的话,可以这样

# 原来调用函数
def A(a, b, c, *args, **kwargs):
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)
A(1,2,3,4,5,6,7,z=1,x=2,v=3)

# 现在可以将参数提出来
args = (4, 5, 6, 7)
kwargs = {'z': 1, 'x': 2, 'v': 3}
A(1, 2, 3, *args, **kwargs)

传参的顺序
普通参数,关键字参数,可变参数(*args , **kwargs)

return

return可以返回值
也可以控制函数在什么时候停止(见到return了,后面代码都不执行)

如果没有写return的话 那么函数的返回值为None

def a():
    pass


print(a())  # None

如果返回了一个值 就返回该值
如果返回了多个值的话,函数的返回值类型为tuple

break是用来结束循环的,return是结束函数的

函数的嵌套

函数体中可以调用其他函数

def a():
    print(0)

def a1():
    a()
    print(123)

def b1():
    a1()
    print(456)

b1()

执行顺序

def a():                # 6
    print(0)            # 7

def a1():               # 4
    a()                 # 5
    print(123)          # 8

def b1():               # 2
    a1()                # 3
    print(456)          # 9

b1()                    # 1

# 10 结束

回调

def a(func):
    func()

def b()
    print("b")

a(b)

递归

就是一个函数在内部调用自身

递归必须要有一个明确的结束条件 否则就进去了一个死循环

lambda表达式

在python中lambda表达式可以看成是匿名函数

举例

def A(func):
    return func
def add1(x):
    return x+1

f = A(add1)        # 经add1函数的引用传到A()中  经过赋值之后f和add1指向同一个函数
a =f(2)
print(a)
---------------------------
def A(func):
    return func

print(A(lambda x:x+1)(2))       # 打印3

一个普通的函数结构

def 函数名(形参列表):
    函数体
    返回值

而lambda表达式

lambda 形参列表:返回值表达式/语句

# 如果形参列表为空的时候 可以写成  lambda : 返回值表达式/语句
a = lambda : print(123)
a()

调用有名字的函数 直接 函数名(参数列表)
如果有返回值的话用外部变量接收

调用一个lambda表达式的话
变量 = lambda表达式 然后变量()
这样的话实际上就是给了匿名函数一个函数名

高阶函数

函数式编程: 把函数当做参数传给另一个函数 以及 返回值中包含函数

map

map类的__init__方法
def __init__(self, func, *iterables)
第2个参数是函数名/匿名函数
第3个参数是可以传一个或多个可迭代对象

# map函数

li = map(lambda x:x+1,[1,2,3,4,5])
print(li)       # <map object at 0x0000019D4715B240>
print(type(li)) # <class 'map'>
print(list(li)) # [2, 3, 4, 5, 6]

简单模拟一下map函数

def add_one(x):
    return x + 1


def mapTest(func, iterable):
    li = []
    for i in iterable:
        res = func(i)
        li.append(res)
    return li


li = mapTest(add_one, [1, 2, 3, 4, 5])
print(li)

还有 func后面跟多少可迭代对象 func的形参就有几个

li = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(li)) # [5, 7, 9]

# 首先 li1[0]作为x li2[0]作为y 传到lambda表达式
# ...

func如果逻辑复杂的话 就在外部定义函数
如果不算复杂的话可以用lambda表达式来解决

比如将[1,2,3] 变成[‘1’,’2’,’3’]

li = list(map(lambda x:str(x),[1,2,3]))
print(li)

# 当然 用列表推导式也能实现
li2 = [str(i) for i in [4,5,6]]
print(li2)

reduce

py2中可以直接用reduce函数
而py3中需要 from functools import reduce

def reduce(function, sequence, initial=None)

from functools import reduce

num = reduce(lambda x, y: x * y, [1, 2, 3, 4])
print(num)      # 24

# 首先 li[0] 作为x  li[1]作为y  
# 上一次的返回值 作为x li[2]作为y
# ...

算阶乘的话可以用reduce

num = reduce(lambda x, y: x * y, range(1, 11))
print(num)  # 3628800

5050也可以

num = reduce(lambda x, y : x + y , range(1, 101))
print(num) 

reduce的第三个参数 是初始值
比如上面的5050
如果初始值传个101的话 返回值就是 5050+101 = 5151

列表转换成字符串也可以用reduce

from functools import reduce

a = [1,2,3]
s = reduce(lambda x,y:str(x)+str(y),a)
print(s)            # 123
print(type(s))      # <class 'str'>

filter

filter的作用是过滤

def __init__(self, function_or_None, iterable)
传入的func可以是None 也可以是一个返回值为布尔值的函数

可迭代对象中的元素传入func,如果函数的返回值为False
那么这个不符合条件的元素会被过滤掉

li = filter(lambda x: True if x < 5 else False, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(list(li))

总结

map(func,*iterable)
将可迭代对象中的每个元素传入到func中 批量进行处理
会得到一个返回值”列表” 是一个map类型对象

map类型的对象可以迭代 也可以转换成list


filter(func,*iterable.init)
func是一个返回值类型为布尔值的函数/lambda表达式
将可迭代对象中的每个元素传入到func中
如果返回值为True的话,元素会被添加到返回值”列表”中 是一个filter类型对象
如果返回值为False的话,元素会被过滤掉


reduce可以理解为把序列进行合并操作
比如序列是[1,2,3]
func是 lambda x,y:x+y 那就等价于 将序列遍历然后进行累加 并返回
func是 lambda x,y:x*y 那就等价于 将序列遍历然后进行累乘 并返回
func是lambda x,y:str(x)+str(y)
那就等监狱 将序列中的所有元素转换成字符串 然后进行拼接

如果有初始值(init)的话,就从初始值开始

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值