我是靠谱客的博主 高大寒风,最近开发中收集的这篇文章主要介绍python-基础-4-函数函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

参考: 教学博客地址1,教学博客地址2,教学博客地址3

函数

一、函数基础

1.1、什么是函数

        函数的作用是非常重要的,函数可以说是现代编程中最小的模块单元,其本质上是子程序,就是可以独立执行一个功能的程序,函数的操作方法是将函数体压入栈中,然后传入参数,在计算完毕之后,将return的值返回到调用处,然后将函数从栈中释放出去.

        函数对于编程的一般意义来讲,是实现一个特定的功能,并且可以反复调用,减少代码量,在python里没有return语句的话会返回None,所以python里没有真正意义上的过程.所有的都是函数.

        面向对象其实是在函数上发展起来的,对象的方法其实就可以看做函数,当然函数在面向对象的语言中也是函数,可以认为面向对象语言是将函数,基础数据类型这些东西做了一个更高层次的封装.

1.2、为何要用函数之不用函数的问题

#1、 代码的组织结构不清晰,可读性差
#2、 遇到重复的功能只能重复编写实现代码,代码冗余
#3、 功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大 

1.3、函数分类

#1、内置函数
为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,参考官网:https://docs.python.org/3/library/functions.html

#2、自定义函数
在一些的场景中内置函数是可能无法满足需求的,这就可能需要根据自身或项目要求来定制自己的函数来实现,后续如果遇到相应的场景,直接设定所定义的函数即可。

1.4、自定义函数

#语法,函数名要能反映其意义
def 函数名(参数1,参数2,参数3,...):
    '''注释'''
    函数体
    return 返回的值

# 一个简单的实例
def hello():
    print("你好")
hello()  		# 直接调用就能显示函数的print结果,但是如果没有return返回过程,那么其结果一定是none

# 比如 login
def login():
    username = input("请输入用户名: ")
    password = input("请输入密码: ")

    if username == "xiong" and password == "123":
        return "登陆通过"
    return "错误"

print(login())

1.5、函数原则及定义

# 1、函数需要先定义,然后在调用, 但A函数调用B,但B函数在A函数之后,那就会报错
def a():
    print("这里是a")
    b()
a()   # 先引用了a函数,但是b函数还没有引用到内存中,就会出现 b函数没有被定义

def b():
    print("这里是b")

# 2、函数定义阶段
    # 函数在引用时啥都不会干,只会加载到内存中,但它一旦被调用就会执行函数内的过程

1.6、有参无参

def play():
    print("玩耍")

def get(num):
    print("你的号码是: {}".format(num))

play()
get(12332112222)

1.7、函数返回值

return-> pring时会直接打印 None
return 1个值->返回1个值
return 逗号分隔多个值->元组
  • 什么时候该有返回值?
    • 调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
    • 通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
  • 什么时候不需要有返回值?
    • 调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
    • 通常无参函数不需要有返回值

1.8、形参与实参

# 形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
  • 位置参数
按照从左到右的顺序定义的参数
	位置形参:必选参数
	位置实参:按照位置给形参传值

def test(v1,v2):		# 2、函数test(形参v1,v2)
	print(v1,v2)		# 3、当调用之后,获取实参 3 5

test(3,5)		# 1、调用 test(传递实参 3 5)
  • 关键字参数
按照key=value的形式定义的实参,无需按照位置为形参传值
注意的问题:
    1. 关键字实参必须在位置实参右面
    2. 对同一个形参不能重复传值

def local(v1, status=False):			 # 2、关键字参数必须在最右边
    return v1 if status else "木有状态"	   # 3、三元表达式 获取任意一个值返回其状态
print(local("hello"))     				 # 1、当有关键字参数时,可以不用传递 默认就是false


# 失败案例, 这种是不可以的
    # non-default argument follows default argument
    def the_test(v1, status=False, v2):	
        return v1 if status else "木有状态"		

    # duplicate argument 'v1' in function definition
    def the_test(v1, v2, v1):      
        return v1 if v2 else "木有状态"
  • 默认参数
# 可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
注意的问题:
    1. 只在定义时赋值一次
    2. 默认参数的定义应该在位置形参右面
    3. 默认参数通常应该定义成不可变类型

# 与关键字参数差不多
  • 可变长参数

    可变长指的是实参值的个数不固定
    而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs
    
    #################################### *args ####################################
    def test(x, y, *args):
        print("x: {} ny: {} nargs: {}".format(x, y, args))
    
    
    test(1, 2, 3, 4, 5, 6, 7, 8)  # args: (3, 4, 5, 6, 7, 8)
    
    # 如果不做处理,那么传递的就是一个元组加列表的形式
    test(1, 2, [1, 2], [111, 22])  # args: ([1, 2], [111, 22])
    
    # 通过 *[] 类似于迭代直接列表做了一个for循环传递到*args当中
    test(1, 2, *[1, 2, 3, 5, 6])  # args: (1, 2, 3, 5, 6)
    
    
    #################################### **kwargs ####################################
    def test(x, **kwargs):
        print("x: {} nkwargs: {}".format(x, kwargs))
    
    
    # kwargs: {'k': '123', 'k2': '234', 'k3': '345', 'k4': '456'}
    test(1, k="123", k2="234", k3="345", k4="456")
    
    # 通过迭代的方式传递,先解开然后在传值, 如果直接传字典会报错
    test(1, **{'k': '123', 'k2': '234', 'k3': '345', 'k4': '456'})
    
    
    ############################ *args + **kwargs ####################################
    def test(*args, **kwargs):
        print("args: {}nkwargs: {}".format(args, kwargs))
    
    
    # args: (1, 2, 3) kwargs: {'k': '123', 'k2': '234'}
    test(1, 2, 3, k="123", k2="234")
    
    # args: (1, 2, 3) kwargs: {'k': '123', 'k2': '234'}
    test(*[1, 2, 3], **{'k': '123', 'k2': '234'})
    

二、对象及嵌套

2.1、函数对象

函数是第一类对象,即函数可以当作数据传递

#1 可以被引用
#2 可以当作参数传递
#3 返回值可以是函数
#3 可以当作容器类型的元素

# 示例  特性
def foo():
    print("foo")

def bar():
    print("bar")

dic = {
    "foo": foo,
    "bar": bar
}

while True:
    chiose = input(">>: ").strip()
    if chiose in dic:
        dic[chiose]()

2.2、嵌套调用

def max(x, y):
    return x if x > y else y

def check(a, b, c, d):
    res1 = max(a, b)			# check嵌套max使用
    res2 = max(c, d)			# 两两比较,在得出最大值
    return max(res1, res2)

print(check(11, 2, 3, 4))

三、名称空间与作用域

  • 什么是名称空间
#名称空间:存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)
  • 名称空间的加载顺序

    python test.py
    #1、python解释器先启动,因而首先加载的是:内置名称空间
    #2、执行test.py文件,然后以文件为基础,加载全局名称空间
    #3、在执行文件的过程中如果调用函数,则临时产生局部名称空间
    
    # 名字的查找顺序
        局部名称空间--->全局名称空间--->内置名称空间
        #需要注意的是:在全局无法查看局部的,在局部可以查看全局的,如下示例
    
    def foo():
        max_num = 111		 # 2、min_num相对于foo来说就是一个局部名称变量了
    
        def foo_two():
            min_num = 2222    # 1、max_num相对于foo_two来说也是一个全局变量
            return min_num
        foo_two()
        return max_num
    
    foo()     
    # 然后Py里直接执行 max_num 会报出 NameError: name 'max_num' is not defined
    
  • 作用域

    #1、作用域即范围
        - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
        - 局部范围(局部名称空间属于该范围):临时存活,局部有效
    #2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
    
    x=11111
    def f1():
        def f2():
            print(x)
        return f2
    
    x = 22222
    
    def f3(func):
        x = 33333
        func()
    
    f3(f1())     # 最终的结果是 22222
    # 先到 全局11111- 22222, 执行f3->f1->f2,f2此时是22222,然后进入x=33333,执行函数func 由于x=33333是局部范围,所以并没有更改x的全局变量,然后在打印 结果为22222
    
  • 作用域查询

    #3、查看作用域:globals(),locals()
    
    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
    locals 是函数内的名字空间,包括局部变量和形参
    enclosing 外部嵌套函数的名字空间(闭包中常见)
    globals 全局变量,函数定义所在模块的名字空间
    builtins 内置模块的名字空间
    
  • global与nonlocal关键字

    global 将局部变量 修改为全局变量, 这个关键字并不建议使用,如果引用全局可变对象,也就是按引用传递,最好将引用复制一份,否则对全局可变对象直接操作,会修改全局可变对象
    
    max = 123
    def f1():
        # global max		# 1、如果引用了global那么它会修改全局变量
        max = 12321
        print(max)
    
    f1()
    print(max)    			# 2、这里得到的结果就是12321
    
    # nonlocal  如果想指定上一层的局部变量,用nonlocal声明
    
    min = "最小值"
    def f2():
        min = "f2里头的"
    
        def f3():
            nonlocal min      # 只修改函数内的上一级
            min = "f3里的"
            print("*" * 10, min)
            
        def f4():     
            print(min)   # f3 修改了f2的min值,此时f4得到的全局变量 f2的min就是 f3的结果了
    
        f3()
        f4()
        print(min)
    
    f2()
    print(min)
    
    ############################  结果为  ############################
        ********** f3里的
        f3里的
        最小值
    

四、闭包

4.1、什么是闭包?

# 内部函数包含对外部作用域而非全局作用域的引用
# 提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,将函数包裹起来

def t1():
    n = 0
    def t2():
        nonlocal n  # 修改上层的n值
        x = n  		# 重新赋值x
        n += 1  	# 每次执行函数+1
        return x  	# 返回修改之后的值

    return t2  # 返回x

c = t1()
print(c())  # 0
print(c())  # 1
print(c())  # 2
print(c())  # 3
print(c.__closure__[0].cell_contents)  #查看闭包的元素  下一次就是4了

4.2、闭包的意义与应用

#闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
#应用领域:延迟计算(原来我们是传参,现在我们是包起来)

from urllib.request import urlopen

def index(url):
    def get():
        return urlopen(url).read()
    return get

bd=index("http://www.baidu.com")   # 得到的是一个内存对象
print(bd().decode('utf-8'))

五、装饰器

装饰器就是闭包函数的一种应用场景

为什么用装饰器

程序中的函数就是具备某一功能的工具, 装饰器就是一个函数,
定义装饰器就是定义一个函数, 只不过装饰器的功能是就是用来给其它函数添加额外的功能,
装饰器( 被装饰的对象 )本身其实是任意可调用的对象, 

软件的维护应该遵循开放封闭原则
开放封闭的原则是: 软件一旦上线运行后对修改源代码是封闭的,对扩展功能是开放的
    装饰器的实现必须遵循的两大原则
   1、不修改被装饰对象的源代码
   2、不修改被装饰对象的调用方式

装饰器语法糖 
	在被装饰的函数上加上 @装饰器 (闭包函数)  等于 函数名=装饰器(函数名)

5.1、无参装饰器

5.1、示例一

简单demo 写法一:  有一定的局限性

import time

def home():
    print("welcome home ")
    time.sleep(2)

def times(func):
    def warpper():
        start = time.time()
        func()     # 执行被装饰的函数
        end = time.time()
        print("装饰器执行的时长为: {}".format(end-start))
    return warpper    # 拿到并返回装饰函数的内存地址

home = times(home)
home()

--------------------------------------------------

demo 第二个

def index():
    print("welcome to index..")
    time.sleep(1)
    return 123

def home(tip):
    print("this price {}".format(tip))

def timmer(func):
    def warpper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        end = time.time()
        print("程序运行时间: {}".format(end-start))
        return res
    return warpper

index = timmer(index)
print(index())
home = timmer(home)
home(100)

--------------------------------------------------

demo 第三个    装饰器语法糖的方式
import time

timmer函数不变

@timmer         #  等于 index = timmer(index)
def index():
	.....
	
@timmer         #  等于 home=timmer(home)
def home(tip):
    print("this price {}".format(tip))


print(index())
home(100)

5.2、有参装饰器

import time

current_user = {"user": None}
def auth(eng):
    def timeer(func):
        def wrapper(*args, **kwargs):
            if current_user["user"]:
                res = func(*args, **kwargs)
                return res

            username = input("请输入用户: ").strip()    # 输入用户 去掉空格
            pwd = input("请输入密码: ").strip()         # 输入密码 去掉空格
            if eng == "file":
                if username == "xiong" and pwd == "123":
                    current_user["user"] = "xiong"
                    print("登陆成功")
                else:
                    print("登陆失败")
            elif eng == "mysql":
                print("mysql登陆")
            res = func(*args, **kwargs)
            return res
        return wrapper
    return timeer

timeer = auth(eng="file")

@timeer
def index():
    print("this's index page")
    time.sleep(1)

@auth(eng="file")
def home():
    print("this's home page")
    time.sleep(1)

index()
home()

装饰器- wraps

**@wraps**接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。

demo-1 - 不带参数的装饰器

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
from functools import wraps

check_auth = {"user": None}


def auth(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if check_auth["user"]:
            res = func(*args, **kwargs)
            return res
        user = input("username >>>: ").strip()
        passwd = input("passwd >>>: ").strip()
        if user == "xiong" and passwd == "123":
            res = func(*args, **kwargs)
            return res
        return "登陆失败"

    return wrapper

@auth         # 相当于是 login=auth(login)
def login():
    return "登陆到了主页"


print(login())

demo-2 - 带参数的装饰器

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
from functools import wraps

check_auth = {"user": None}


def check_auth_types(auth_type="file"):
    def auth(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            if check_auth["user"]:
                res = func(*args, **kwargs)
                return res
            if auth_type == "file":
                print("文件认证")
                user = input("username >>>: ").strip()
                passwd = input("passwd >>>: ").strip()
                if user == "xiong" and passwd == "123":
                    res = func(*args, **kwargs)
                    return res
            if auth_type == "mysql":
                return func(*args, **kwargs),"数据库认证"
            return "登陆失败"

        return wrapper

    return auth


x = check_auth_types(auth_type="mysql")

@check_auth_types(auth_type="mysql")  # 也可以是 @x
def login():
    return "登陆到了主页"
#  check_auth_types 传递参数,返回给了auth, 做为有参装饰器继续往里传递执行

print(login())

多个装饰器

# 叠加多个装饰器
# 1. 加载顺序(outter函数的调用顺序):自下而上
# 2. 执行顺序(wrapper函数的执行顺序):自上而下

六、迭代器

迭代器概念

# 迭代器即迭代的工具,那什么是迭代呢?
# 迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值

while True: # 只是单纯地重复,因而不是迭代
    print('===>') 	# 一个无脑的死循环

lis=[1,2,3]
count=0
while count < len(lis): # 迭代 重复的过程,但每次迭代都是下一次的初始值
    print(lis[count])
    count+=1			# 每次加1, 如果没有+1 那就不是下一次的初始值 == 一个无脑的死循环

为何要有迭代器?什么是可迭代对象?什么是迭代器对象?

#1、为何要有迭代器?
	对于序列类型:字符串(str)、列表(list)、元组(tuple),我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器

#2、什么是可迭代对象?
    可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下 
    # 也可通过 dir() 可查看内置函数方法 __iter__
    'hello'.__iter__
    (1,2,3).__iter__
    [1,2,3].__iter__
    {'a':1}.__iter__
    {'a','b'}.__iter__
    open('a.txt').__iter__

#3、什么是迭代器对象?
    可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
    执行迭代器对象是__next__得到的是迭代器下一个值
    执行迭代器对象的__iter__得到的仍然是迭代器本身
    而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象

文件类型是迭代器对象
open('a.txt').__iter__()
open('a.txt').__next__()

# 使用
dic = {'a': 1, 'b': 2, 'c': 3}
iter_dic = dic.__iter__() #得到迭代器对象,迭代器对象即有__iter__又有__next__,但是:迭代器.__iter__()得到的仍然是迭代器本身
print(iter_dic, type(iter_dic))
# <dict_keyiterator object at 0x0000020BAF49BB88> <class 'dict_keyiterator'>

print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())
# print(iter_dic.__next__())  # StopIteration

#4、注意:
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

for循环 - 迭代器

dic = {'a': 1, 'b': 2, 'c': 3}

for i in dic:  	   # dic.__iter__()  得到迭代器对象
    print(dic[i])  # 每次循环都是 xx.__next__() 获取值,直到StopIteration

# for循环的工作原理
# 1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
# 2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
# 3: 重复过程2,直到捕捉到异常StopIteration,结束循环

迭代器优缺点

#优点:
  - 提供一种统一的、不依赖于索引的迭代取值方式
  - 惰性计算,节省内存

#缺点:
  - 迭代器的取值不如按照索引的方式灵活,它只能往后取而不能往前退
  - 无法预测迭代器的个数
  - 无法获取长度(只有在next完毕才知道到底有几个值)
  - 一次性的,只能往后走,不能往前退

七、生成器-yield

# 生成器 generator
	生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码
    
# 生成器函数
	函数体中包含yield语句的函数,返回生成器对象
    生成器对象,是一个可迭代对象,是一个迭代器
    生成器对象,是延迟计算、惰性求值的

示例

def yie():
    for i in range(5):
        yield i


print(type(yie))
print(type(yie()))   # <class 'generator'>
y = yie()			 # 通过生成器生成的对象都是一个内存地址 
for i in y:
    print(i)

普通的函数调用 fn(),函数会立即执行完毕,但是生成器函数可以使用next函数多次执行
生成器函数等价于生成器表达式,只不过生成器函数可以更加复杂

yield from

def yie():
    for x in range(100): yield x

# 等价于
def yie():
    yield from range(100)

yield from 是python3.3出现的新语法,  是fro item in iterable: yield item形式的语法糖

八、表达式

1.1、三元表达式

条件成立时的返回值, if 条件 else 条件不成立时时的返回值

def check(x,y):
    if x > y:
        return x
    else:
        return y

x=10
y=20

# 三元表达式   如果x 大于 y 最左边为x (true),最右边为如果不大于的结果
res = x if x > y else y   # 如上的函数可以简化为这种三元表达式
print(res)

1.2、列表生成式

# 重要: 把列表推导式的[]换成()就是生成器表达式

li=[]
for i in range(10):
    li.append(i)
print(li)

# 在列表中循环, 然后将循环的值放到左右就能直接append了
li2 = [i for i in range(10)]
print(li2)

# 列表生成式 只能 for if 不能跟else
name = ["xiong", "xiong2", "xiong3"]
li3 = [i for i in name if i not in "xiong"]
print(li3)

# 循环1到10如果小于5 那么i就加1,
li4 = [i+1 for i in range(1,10) if i<5]
print(li4)

1.3、生成器表达式

# 把列表推导式的[]换成()就是生成器表达式

x = (i for i in range(10))
print(x, type(x))
# <generator object <genexpr> at 0x00000231AB5725E8> <class 'generator'>

# 使用生成器的优点:省内存,一次只产生一个值在内存中,每次执行next只会取出一个

with open("a.txt", "r") as files:
    # 生成器刚开始造的时候 代码不会执行, 只能在.__next() 调用的时候才会运行
    nums = (len(line) for line in files)
    print(max(nums))

1.4、字典生成式

keys=["name", "age", "sex"]
values = ["xiong", "100", "male"]
# zip 拉链函数 将两个值对应成元组 如 (name, xiong)
print(list(zip(keys,values)))

res = {k:v for k,v in zip(keys, values)}
print(res)
# {'name': 'xiong', 'age': '100', 'sex': 'male'}

1.5、元组生成器

tuple(random.randint(0, 255) for i in range(3))
(241, 97, 220)

九、递归与二分法

1.1、什么是递归

# 1、什么是递归
	递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用
   	递归就是一个无何止的重复过程, 递归必须要有一个明确的结束条件

# 2、代码特点
    - 函数内部的 代码 是相同的,只是针对 参数不同,处理的结果不同
    - 当参数满足一个条件时,函数不再执行
      - 这个通常称为递归的出口,否则会出现死循环

# 3、递归阶段
    递归必须要有两个明确的阶段
    	递推: 一层一层递归调用下去,每进入下一层递归问题的规模都必须有所减少
        回溯: 递归必须要有一个明确的结束条件,在满足该条件时结束递推,开始一层一层回溯	
    递归的精髓在于通过不断地重复逼近一个最终的结果

# 4、递归层级
    print(sys.getrecursionlimit())  # 获取递归的层级, 1000层
    sys.setrecursionlimit(next())	# 设置递归的层级,但没有多大的意义,如果太多可能会导致内存崩掉

# 5、为什么使用递归
	递归本身就是一个重复的过程,while循环本身也是做一个重复的过程,递归能做的事 循环也都能满足,但比如是如下这种使用while就会显得比较麻烦,而直接使用递归就能得出想要的结果
    
l = [1, [2, [3, [4, [5, [6, [7, [8]]]]]]]]

def dl(l):
    for its in l:
        if type(its) is list:
            dl(its)
        else:
            print(its)
dl(l)

# 示例2 
def age(n):
    if n == 1: return 10     
    return age(n-1)+2      // 递推到n等于1时返回10,  然后取到10每次加2  

print(age(5)) 循环五次

1.2、递归-二分法

# 查找列表
search_list = [1, 3, 5, 7, 9, 11, 23, 33, 44, 112, 115, 125, 136, 147, 199]

def search(search_list, num):
    two_search = len(search_list) // 2  # # 每次取一半
    if two_search == 0:
        print("没有这个")
        return
    if num > search_list[two_search]:
        n = search_list[two_search:]
        search(n, num)
    elif num < search_list[two_search]:
        n = search_list[:two_search + 1]
        search(n, num)
    else:
        print("找着了")

search(search_list, 112)

十、匿名函数

# 有名函数,调用函数名可以一直重复使用
# 有名函数
def fun(x, y):
    return x + y

print(fun(1, 4))

# 匿名函数, 通常于其它函数一起使用,直接执行就的是一个内存地址, :后的x+y就相当于是return x+y
print(lambda x, y: x + y)  # <function <lambda> at 0x000002948ACD47B8>
# 与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字

示例

salaries = {
    "axiong": 10000,
    "wen": 99000,
    "hei": 19999,
    "bai": 22222
}

def fun(k):
    return salaries[k]

max工作原理:

1、 先将可迭代对象变成 迭代器对象
2、 res=next(可迭代器对象), 将res当作参数传递给max函数,然后将该函数的返回值当作判断依据

# 最大值就是w,但func却只需要一次性使用,这里就可以直接使用匿名函数了
# max(iterable, *[, default = obj, key = func]) -> value
# max(arg1, arg2, *args, *[, key = func]) -> val, key=funue
print(max(salaries, key=fun))
print(max(salaries, key=lambda k:salaries[k]))    # wen
print(min(salaries, key=lambda k:salaries[k]))    # axiong

sorted

# sorted 排序
print(sorted(names, reverse=True))  # 从大到小
print(sorted(names, reverse=False))  # 从小到大

# 与匿名函数进行配置 sorted(可迭代对象, key=匿名函数, 排序=True/False)
print(sorted(names, key=lambda x:x, reverse=True))
print(sorted(names, key=lambda x:x, reverse=False))

map工作原理

1、 先将可迭代对象变成 迭代器对象
2、 res=next(可迭代器对象), 将res当作参数传递给第一个参数指定的函数,然后将该函数的返回值当作map的结果之一
3、 映射: 将原来的值映射成新的值 

# 映射,将列表的旧值映射为新的值
m_name = map(lambda x: x + "XXS", names)  # ['heiXXS', 'baiXXS', 'hongXXS', 'nvXXS']
print(list(m_name))  # 如果不使用list 打印的话  打印的结果就是迭代器对象,需要通过 __next__

# 与如下的列表生成式相等
m_name = [name + "xxxx" for name in names]
print(m_name)

filter工作原理

1、 先将可迭代对象变成 迭代器对象
2、 res=next(可迭代器对象), 将res当作参数传递给第一个参数指定的函数,然后filter会判断函数的返回值 的真假,如果为真则留下res

names = ["xiongge", "wo", "ni", "hao"]

#  列表生成器
res = [name for name in names if name.endswith("ge")]
print(res)

# filter 过滤器  filter(匿名函数, 可迭代对象)
f_name = filter(lambda x: not x.endswith("ge"), names)
print(f_name)  # <filter object at 0x000002B9433EB240>
print(list(f_name))  # ['wo', 'ni', 'hao']
# 使用lamba过滤  filter   过滤某个条件     
语法:  lambda i: i %2, range(10)   等于是下面这个函数 
def t1(i):
    temp=[]
    for i in range(10):
        temp.append('{0}'.format(i%2))
    return temp

y=list(filter(lambda i:i %2, range(10)))
print(y)  # [1, 3, 5, 7, 9]

map() 可以批量处理数据,与filter() 相比,输入可以是多个可迭代对象
xx = map(lambda x:x, range(10))
print(list(xx))   # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

使用递归打印斐波那契数列

# 使用递归打印斐波那契数列

def fib(n):
    a, b = 0, 1
    while a < n:
        print(a, end=" ")
        a, b = b, a + b
    print(" ")


fib(20)


def flb(a, b, stop):
    if a > stop:
        return
    print(a, end="t")
    flb(b, a + b, stop)

# 一个嵌套很多层的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用递归取出所有的值
l = [1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15]]]]]]]
def gl(l):
    if type(l) is list:
        for li in l:
            gl(li)
    else:
        print(l, end="t")

gl(l)

十一、内置函数

官方内置函数

Built-in Functions
abs()delattr()hash()memoryview()set()
all()dict()help()min()setattr()
any()dir()hex()next()slice()
ascii()divmod()id()object()sorted()
bin()enumerate()input()oct()staticmethod()
bool()eval()int()open()str()
breakpoint()exec()isinstance()ord()sum()
bytearray()filter()issubclass()pow()super()
bytes()float()iter()print()tuple()
callable()format()len()property()type()
chr()frozenset()list()range()vars()
classmethod()getattr()locals()repr()zip()
compile()globals()map()reversed()__import__()
complex()hasattr()max()round()

11.1、需要了解的函数

# 列表中所有值为真,则为真,如果为空也是真
	print(all([1, 2, 3, 4, 5]))     # True

# 有一个bool值为真,则为真,  如果为空则是false
	print(any([1, 0, False]))       # True

# 十进制转二进制
	print(bin(11))                  # 0b1011
    
# oct  十进制转八进制
    print(oct(9))                   # 0o11

# hex 十进制转十六进制
	print(hex(19))                  # 0x13

# chr()  将数字转换成字符
	print(chr(103))                 # g

# ord 将字符串转成数字
	print(ord("g"))                 # 103

# dir   判断函数里的所有属性
	print(dir(True))                # ['__abs__', '__add__',....]

# pow (3,2,2)   3的2次方取余
	print(pow(5,2,2))               # 1
    
# round(3.5)  四舍五入
    print(round(3.99))              # 4
    
callable()   判断函数是否可被调用

divmod(10,3)     分页使用,  比如31 就是  3,1 总共有30页 余1

最后

以上就是高大寒风为你收集整理的python-基础-4-函数函数的全部内容,希望文章能够帮你解决python-基础-4-函数函数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部