我是靠谱客的博主 魁梧枫叶,最近开发中收集的这篇文章主要介绍python的函数认识函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

认识函数

:在一个完整的项目中,某些代码会被反复使用。那么将某段代码封装成函数,当我们要使用功能的时候直接调用函数即可

  • 本质:函数是对功能的封装
  • 优点:简化代码结构,增加代码的复用度
  • 定义函数
    • 格式
      def 函数名(参数列表):
      语句
      return 表达式

    • 说明

      • def:函数代码块以def关键字开始
      • 函数名:遵守标识符规则
      • ():参数列表的开始和结束
      • 参数列表:是函数的调用者给函数的的信息,多个信息之间用逗号分隔,如果没有信息,那么小括号中什么都不用写(小括号不可以省略)
      • 冒号:函数的内容以冒号开始
      • 语句:函数封装的功能
      • return:一般用于结束函数,并返回给函数的调用者一些信息,“表达式”就是要返回的数据。如果没有显示的写return语句,默认return返回None
    • 注意:
      1、定义函数时,程序时不会执行函数,当调用函数时才会执行
      2、函数的使用必须在定义之后

    • 函数调用的本质:实参给形参赋值的过程

  • 使用函数
    • 格式:函数名(参数列表)
    • 说明
      函数名:要使用某个功能函数的名字
      ():参数列表的开始和结束
      参数列表:调用者给函数的数据

简单使用

  • 无参函数
def my_print():
    print("hello world")
my_print()
my_print()
my_print()
  • 带参数的函数
    • 形式参数(形参):变量,可以在函数内部使用
    • 参数的数量理论上是无限制的,但是在实际开发中最好不要超过6、7个,参数是没有类型的,在函数调用时赋值后才有类型。
def my_print(name, age, hobbys):
    print("%s is a good man!He is %d years old. He like"%(name, age), hobbys)
# 函数在调用时,需要给函数按顺序传递数据
# 实际参数(实参):值
my_print("tom", 17, ["power", "money"])

函数的返回值

#编写函数,实现计算两个数的和
def my_sum(x, y):
    sum = x + y
    # 以后开发中尽量不要在函数中进行打印
    # print("x + y = %d"%sum)
    # 将得到的结果返回给函数的调用者
    return sum

# ret接收my_sum函数运行后的返回值的值
ret = my_sum(1, 2)
print("ret =", ret)

#返回值可以一次性返回多个值
def func():
    x = 200
    y = 150
    return x, y

# m, n = (x, y)
m, n = func()
print(m, n)
print(type(m), type(n))
#200 150
#<class 'int'> <class 'int'>

参数传递

  • 值传递:传递不可改变数据
def func1(num):
    num = 10
a = 401
func1(a)
print("a =", a)		#401
  • 引用传递:传递可变数据类型
    • 本质还是值传递,传递的是地址
def func2(arr):
    print(id(arr))		#35472328
    arr[0] = 100   #arr是li哪个列表的地址
    # arr = [4,5,6]
    print("----------", arr)	#[100, 2, 3, 4, 5]
li = [1,2,3,4,5]
print(id(li))	#35472328
func2(li)	
print(li)		#[100, 2, 3, 4, 5]
  • 关键字参数:允许函数调用时参数的顺序与定义时不一致
def func(name, age):
    print("%s is a good man!He is %d years old!"%(name, age))
func(age=16, name="tom")
  • 默认参数:如果参数未传递,让形参使用默认值
    • 使用默认参数,如果未传递使用给出的默认值,如果传递了使用传递的值
    • 注意:在定义函数时尽量将默认参数写在最后
def func(name, age=18):
    print("%s is a good man!He is %d years old!"%(name, age))
func("tom")
func("tom", 23)
  • 不定长参数:能处理比当初定义时更多的参数
    • 在形参变量前加了星号,变量会存放所有未命名的变量的参数,如果在函数调用时没有指定参数,他就是个空元组
def func2(name, age, *args):
    print("%s is a good man!He is %d years old!"%(name, age))
    print(args, type(args))
 func2("tom", 18, "power", "money", "book")
func2("tom", 19)	#() <class 'tuple'>

# **代表着键值对字典,和*差不多
# 多于的关键字参数被kwargs接收
def func3(name, age, **kwargs):
    print("%s is a good man!He is %d years old!"%(name, age))
    print(kwargs, type(kwargs))	#{'x': 1, 'y': 2, 'z': 3} <class 'dict'>
    print(kwargs.get("x"))
func3("tom", age=16, x=1, y=2, z=3)

#混合使用
def func(a, b, *args, **kwargs):
    print(a, b, args, kwargs)
func(1,2,3,4,5,7,x=1,y=2,z=3)
#1 2 (3, 4, 5, 7) {'x': 1, 'y': 2, 'z': 3}

匿名函数

  • 概述:不在使用def语句这样的标准的形式定义函数,使用lambda来创建匿名函数

  • 特点:
    1、lambda只是一个表达式,函数体比def简单的多
    2、lambda主体是一个表达式而不是代码块,仅能在lambda表达式中封装有限的逻辑
    3、lambda函数拥有自己的命名空间,且不能访问自有参数序列之外或全局命名空间里的参数
    4、虽然lambda函数看起来只能写一行却不同于c和c++的内联函数,后者的目的是调用小函数时不占栈内存而增加运行效率

  • 格式:lambda [arg1[, arg2[, arg3, ……]]]:expression

  • 作用:作为参数传递,实现回调,简化代码

my_sum = lambda x, y: x + y
ret = my_sum(1, 2)
print(ret)

函数的特殊使用(装饰器前身)

  • 函数也是一种数据,所以可以用变量来保存,且可以当做参数传递
  • 函数名也是一种特殊的变量
  • 作用:作为回调函数使用
def my_sum(x, y):
    return x + y
def func(f, m, n):
    return f(m, n)
ret = func(my_sum, 4, 5)
print(ret)

函数的作用域

  • 作用域:变量可以使用的范围,程序的变量并不是在哪个位置都可以访问的,访问的权限决定于变量是在哪里赋值的
  • 作用域的划分:
    1、局部作用域(L)
    2、闭包函数外到函数中(E)
    3、全局作用域(G)
    4、内建作用域(B)
  • 变量查找的规则
    L->E->G->B
    首先在自身作用域中查找,找不到的话依次向上级作用域中查找,注意不会向低级作用与中查找
  • python中只有模块、类以及函数才会引入新的作用域,其他代码块(比如if、elif、else、for、while、try、except等)是不会引入新的作用域的
num3 = 3
def func():
    num4 = 4 #局部变量
    print("num3 = %d"%(num3))# 在局部作用域中可以使用上级作用域中的变量
    print("------------", num4)
    def a():
        print("num4 = %d"%(num4))
    a()
func()
# print("num4 = %d"%(num4)) #在全局作用域中无法使用局部作用域中的变量
  • 修改全局变量的值
num = 401
def func():
    # 需要将定义的变量声明成全局变量
    global num
    # 在函数的内部可以直接获取全局变量的值,但是不能直接修改全局变量的。直接修改全全局变量的值,相当于在局部作用域中新建一个局部变量
    num = 402
    print("1-num = %d"%num)	#1-num = 402
func()
print("2-num = %d"%num)	#2-num = 402

  • 修改嵌套作用域中的变量
a = 1
def func1():
    c = 10
    def func2():
        # 想要修改嵌套作用域中的变量,需要将其声明成嵌套作用域中的变量
        nonlocal c
        # 可以直接获取嵌套作用域中变量的值,如果直接修改相当于在当前作用域新建一个局部变量
        c = 20
        a = 3
        print("1--c = %d"%c)	#1--c = 20
        print("1--a = %d" % a)	#1--a = 3
    func2()
    print("2--c = %d" % c)	#2--c = 20
    print("2--a = %d" % a)	#2--a = 1
func1()
print("2--a = %d" % a)	#2--a = 1
  • 利用闭包突破作用域链
  • 概念:在函数体中定义内部函数,并且使用了外部函数的变量,然后把内部函数返回,那么这个内部函数就是闭包
  • 优点:避免污染全局环境,这样就可以在函数体外使用函数体中定义的变量
  • 缺点:数据长期驻留在内存中,造成内存极大的浪费
  • 注意:尽量避免使用闭包
    • 可能产出的BUG
    def a():
    li = [] #存储函数
    for i in range(0, 3):
        def f():
            print("-------", i)
        li.append(f)
    return li
    #i
    l = a()
    l[0]()	#------- 2
    l[1]()	#------- 2
    l[2]()	#------- 2
    
    

python内建函数

map&reduce

  • 原型:map(fn, lsd)

  • 参数:
    fn:函数
    lsd:集合

  • 功能:将传入的函数fn依次作用到lsd集合中的每个元素,并把结果作为新的Iterator返回

  • 原型:reduce(fn, lsd)

  • 参数:
    fn:函数
    lsd:集合

  • 功能:传入的fn函数作用在lsd集合中,这个fn函数必须接受两个参数,reduce把结果继续和序列的下一个元素做累积运算
    reduce(f, [4, 5, 6, 7, 2, 3])==>f(f(f(f(f(4, 5), 6), 7), 2), 3)

#map函数
def chr2int(chr):
    return ord(chr) - ord('0')
ret = map(chr2int, "456723")
print(ret, type(list))	#<map object at 0x00000000023A9630> <class 'type'>
print(list(ret))	#[4, 5, 6, 7, 2, 3]

#导入reduce方法
from functools import reduce
def f(x, y):
    return x * 10 + y
res = reduce(f, [1,2,3,4])
print(res)	#1234

# 联合map&reduce实现字符串转数字
s = "456723" #  567834
def str2int(sr):
    #数据处理方法
    def chrToint(chr):
        return ord(chr) - 48
    #数据整合方法
    def my_sum(x, y):
        return x * 10 + y
    return reduce(my_sum, map(chrToint, sr))
ret = str2int(s)
print(ret)

filter过滤器

  • 原型:filter(fn, lsd)
  • 参数:
    fn:函数
    lsd:集合
  • 功能:用于过滤序列,把出入的fn函数依次作用在lsd集合中的每个元素上,然后根据返回值是True还是False决定是否保留该元素,True表示留下,False表示过滤掉
#过滤出偶数
def f(num):
    if num % 2 != 0:
        return False
    return True
li = [1,2,3,4,5,6,7,8,9,10]
res = filter(f, li)
print(li)
print(res)		#<filter object at 0x00000000023C5F98>
print(list(res))	#[2, 4, 6, 8, 10]

sorted函数

  • 排序算法
    • 冒泡排序
    • 选择排序
    • 快速排序
  • 效率问题:在数据量比较小时,这三者的效率差不多,但是当数据量多时“快速排序”的效率明显很高
冒泡排序
li = [1,2,3,4,5]
for i in range(0, len(li)-1):
    for j in range(0, len(li)-1-i):  # 0     0 1 2 3
        if li[j] < li[j+1]:
            temp = li[j]
            li[j] = li[j+1]
            li[j+1] = temp
print(li)
快速排序
li2 = [1,3,2,5,4]
li2.sort()
li2.reverse()
print(li2)
sorted
  • 原型:sorted(lsd, key=None, reverse=False)
  • 参数:
    lsd:集合
    key:排序规则,是函数
  • 功能:排序,可以自定义排序规则
li3 = [2,3,1,5,4]
li4 = sorted(li3)# 默认升序
#[1, 2, 3, 4, 5]
# 按照数据的绝对值大小排序
li5 = [2,-3,1,-5,4]
li6 = sorted(li5, key=abs)
print(li6)
#降序排序
li7 = [2,-3,1,-5,4]
li8 = sorted(li7, reverse=True, key=abs)
print(li8)
# 字符串长度排序
li9 = ["a", "aaaa", "aaa", "aaaaa", "aa", "aaaaaa"]
li10 = sorted(li9, key=len)
print(li10)
# 自定义排序标准
def func(x):
    return len(x) * -1
li11 = sorted(li9, key=func)
print(li11)
函数实现排序求第二大数
#假设法
def func(arr):
    if arr[0] >= arr[1]:
        max = arr[0]
        second = arr[1]
    else:
        max = arr[1]
        second = arr[0]
    index = 2
    while index < len(arr):
        if arr[index] > second:
            if arr[index] < max:
                second = arr[index]
            elif arr[index] > max:
                second = max
                max = arr[index]
        index += 1
    return second
 for i in range(0, 10)
 	 li.append(int(input()))
ret = func(li)
print("第二大值为:%d"%ret)

装饰器

  • 是一个闭包,把一个函数作为参数然后返回一个替代版函数,本质上就是一个返回函数的函数
  • 在不修改原函数的前提下增加函数的功能,最好使用装饰器实现
def func():
    print("tom a good man")
def addFunc():
    print("***********")
    func()
addFunc()
#输出
***********
tom a good man

简单使用装饰器

参数f:你要给哪个函数增加功能,那么在调用wrapper函数时就传递该函数
def wrapper(f):
    # inner即为替代版函数,要实现原函数的功能
    def inner():
        # 在原函数基础上增加新的功能
        print("************")
        # 实现原函数功能
        f()
    return inner


def func():
    print("tom is a good man")

#
************
tom is a good man

带参数的装饰器

#在不修改say原函数的前提下,增加say的功能,如果age小于等于0就使用0
def say(name, age):
    print(44444)
    return "%s is a good man!He is %d years old!"%(name, age)
def wrapper(f):
    # 原函数的参数在inner函数这里传递
    print('111')
    def inner(name, age):
        print(3333)
        #增加功能
        if age <= 0:
            age = 1
        res = f(name, age)
        return res
    print(2222)
    return inner
say = wrapper(say)
print(say("tom", -18))
#输出
111
2222
3333
44444
tom is a good man!He is 1 years old!

使用@符号的装饰器

python2.4支持使用@将装饰器应用在函数上,只需要在函数定义时加上"@装饰器名称"即可完成装饰

def wrapper(f):
    def inner(name, age):
        if age <= 0:
            age = 1
        return f(name, age)
    return inner
@wrapper   #相当于 say = wrapper(say)
def say(name, age):
    return "%s is a good man!He is %d years old!"%(name, age)
print(say("tom", -16))
#输出
tom is a good man!He is 1 years old!

通用装饰器

def wrapper(f):
    #inner接收不定长参数
    def inner(*args, **kwargs):
        print("**************")
        return f(*args, **kwargs)
    return inner


@wrapper
def func1(name, age):
    return "%s is a good man!He is %d years old"%(name, age)

@wrapper
def func2(name, height, weight):
    return "%s is %d cm %d kg!"%(name, height, weight)

print(func1("tom", 18))
print(func2("sum", 175, 80))
#

**************
tom is a good man!He is 18 years old
**************
sum is 175 cm 80 kg!

装饰器带参数

def wrapper(count=3):
    def deco(f):
        def inner(*args, **kwargs):
            for i in range(count):
                f(*args, **kwargs)
        return inner
    return deco


@wrapper()
def say(name, age):
    print("%s is a good man!He is %d years old!"%(name, age))
say("tom", 18)
#
tom is a good man!He is 18 years old!
tom is a good man!He is 18 years old!
tom is a good man!He is 18 years old!

多个装饰器

装饰时:从距离近的装饰器开始装饰
执行时:从距离远的装饰器内部函数开始执行

def wrapper1(f):
    def inner1(*args, **kwargs):
        print("enter inner1")
        res = f(*args, **kwargs)
        print("exit inner1")
        return res
    return inner1

def wrapper2(f):
    def inner2(*args, **kwargs):
        print("enter inner2")
        res = f(*args, **kwargs)
        print("exit inner2")
        return res
    return inner2

def wrapper3(f):
    def inner3(*args, **kwargs):
        print("enter inner3")
        res = f(*args, **kwargs)
        print("exit inner3")
        return res
    return inner3
@wrapper1
@wrapper2
@wrapper3
"""
inner3 = wrapper3(func)
inner2 = wrapper2(inner3)
inner1 = wrapper1(inner2)
func = inner1
"""
def func():
    print("tom is a good man")
func()
#输出
enter inner1
enter inner2
enter inner3
tom is a good man
exit inner3
exit inner2
exit inner1

装饰器的使用场景

  • 1、参数、结果的检查
  • 2、缓存
  • 3、计数
  • 4、日志
  • 5、统计
  • 6、权限管理
  • 7、重试

装饰器计算函数运行时间

def wrapper(f):
    def inner(*args, **kwargs):
        t1 = time.time()
        res = f()
        t2 = time.time()
        print("程序运行:%f"%(t2-t1))
        return res
    return inner


@wrapper
def func():
    print("tom is a good man")
    time.sleep(2)
    print("tom is a nice man")
func()
'''
tom is a good mam
tom is a nice man
程序运行:2.32424534秒
'''

装饰器计数函数执行次数

def count(f):
    index = 0
    def inner(*args, **kwargs):
        nonlocal index
        index += 1
        res = f(*args, **kwargs)
        print("第%d次执行"%(index))
        return res
    return inner
@count
def func():
    print("tom is a good man")
func()
func()
func()
'''
tom is a good man
第1次执行
tom is a good man
第2次执行
tom is a good man
第3次执行

'''

retry装饰器

import random
import time
#count 失败后最多尝试次数  wait表示失败后等待的时间  exceptions表示捕获异常的种类,是个元组
def retry(count=3,wait=0, exceptions=(Exception,)):
    def deco(f):
        def inner(*args, **kwargs):
            for i in range(count):
                try:
                    res = f(*args, **kwargs)
                except exceptions as e:
                	#最后一次不用等到直接返回
                    if i != count - 1:
                        time.sleep(wait)
                    continue
                else:
                    return res
            print("函数运行失败")
        return inner
    return deco
@retry(wait=3)
def func():
    num = random.choice([1,2,3,4])
    print("*************", num)
    if num <= 3:
        num / 0

func()
'''
如果函数执行三次所得到的的数都有异常则最后提示函数运行失败
'''

类装饰器

  • 用装饰器实现单例
def single(fun):
    def __single():
        return hasattr(fun,'single') and getattr(fun,'single') or setattr(fun,'single',fun()) or getattr(fun,'single')
    return __single

@single
class Person():
    pass

p1 = Person()
p2 = Person()
print(p1)
print(p2)
print(p1 is p2)
'''
<__main__.Person object at 0x00000000028742B0>
<__main__.Person object at 0x00000000028742B0>
True
'''
  • 给每个类添加一个数据属性和一个函数属性
def Decorator(obj):# print(School.__dict__)
   #添加数据属性
   obj.addr = "北京市"
   def price():
       pass
   #添加函数属性
   obj.price = price
   return obj

@Decorator          #相当于执行 School = Decorator(School)
class School():
   def __init__(self,name,price):
       self.name =name
       self.price =price

#打印类的属性字典
print(School.__dict__)
'''
{'__module__': '__main__', '__init__': <function School.__init__ at 0x00000000022B7BF8>, '__dict__': <attribute '__dict__' of 'School' objects>, '__weakref__': <attribute '__weakref__' of 'School' objects>, '__doc__': None, 'addr': '北京市', 'price': <function Decorator.<locals>.price at 0x00000000022B7B70>}

'''
  • @property装饰器的原理
class Myproperty():
    def __init__(self,fun):
        print("执行Myproperty类的构造方法")   #调用Myproperty类时会首先运行它
        self.fun = fun
    def __get__(self, instance, owner):
        """
        :param instance: 代表school实例本身
        :param owner:  代表类School本身
        :return:返回参数为实例的实例方法
        """
        print('调用Myproperty的属性时将执行此方法')
        return  self.fun(instance)

class School():
    """
    @name:学校名字
    @addr:学校地址
    @price:学费
    @num:招生人数
    """
    def __init__(self,name,addr,price,num):
        self.name =name
        self.addr =addr
        self.price =price
        self.num =num
    # @property
    @Myproperty    #等价于-->>total=Myproperty(total)
    def total(self):
        "求总的学费"
        return  self.price*self.num

school = School('北大','北京市',12000,6000)
print(school.total)
'''
执行Myproperty类的构造方法
调用Myproperty的属性时将执行此方法
72000000
'''

可迭代对象

  • 概念:可以直接作用于for循环的对象称为可迭代对象(Iterable)

  • 可以直接作用于for循环的数据类型:
    1、集合数据类型(list、tuple、dict、set、string)
    2、generator,包含生成器和带yield的generator function

  • 说明:可以使用isinstance()函数判断一个对象是否是可迭代对象,是则返回True,否则返回False

from collections import Iterable

print(isinstance([], Iterable))	#True
print(isinstance((), Iterable))	#True
print(isinstance({}, Iterable))	#True
print(isinstance(set([]), Iterable))	##True
print(isinstance("", Iterable))	#True
print(isinstance(100, Iterable))	#False

列表生成式

  • 作用:python内置的非常简单并且强大的可以用来生成列表的生成式
# 早期方式生成列表
# 缺点:只能生成简单的列表
print(list(range(1, 11)))
#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 列表生成式生成列表
li2 = [x * x for x in range(1, 11)]
print(li2)
#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 列表生成式的for循环后可以加判断
li3 = [x * x for x in range(1, 11) if x % 2 != 0]
print(li3)
#[1, 9, 25, 49, 81]

# 排列、组合、排列组合
# "ABC"   "123"
# 密码  A1   A2   A3   B1   B2  B3   C1  C2  C3
li4 = [x+y+z for x in "ABC" for y in "123" for z in "abc"]
print(li4)
#['A1a', 'A1b', 'A1c', 'A2a', 'A2b', 'A2c', 'A3a', 'A3b', 'A3c', 'B1a', 'B1b', 'B1c', 'B2a', 'B2b', 'B2c', 'B3a', 'B3b', 'B3c', 'C1a', 'C1b', 'C1c', 'C2a', 'C2b', 'C2c', 'C3a', 'C3b', 'C3c']

生成器

  • 概念:
    通过列表生成式,可以直接创建一个列表。所有的数据都会存到内存中,受内存的限制,列表的容量是有限度的。如果有10000000个数据,如果我们只需要访问前几个元素,后面的元素基本不会访问,那么造成内存的浪费
    如果列表中的元素可以按照某种算法推导出来,那么我们在循环遍历列表时不断推导后面的元素,从而节省大量内存。在python中,这种一边循环一边推导的机制称为生成器(generator)
# [1,2,3,4,5,6,7,8,9,10]

#创建生成器
# 1、修改列表生成式:将列表生成式的[]改为()
g = (x for x in range(1,6))
print(g)	#<generator object <genexpr> at 0x0000000001E15B48>
print(type(g))	#<class 'generator'>
#生成器特点:可以通过next()函数得到generator的下一个值
print(next(g))
print(next(g))
print(next(g))
print(next(g))

# 当所有元素都拿出来后在执行next()会得到StopIteration异常
# print(next(g))
print(next(g))
# print(next(g))

# 遍历
# while 1:
#     print(next(g))

#以后一般都是使用for循环来迭代生成器,不需要关心StopIteration异常
for i in g:
    print(i)

函数实现生成器

  • 推导的算法比较复杂,用列表生成式的for循环无法实现的时候可以选择使用函数生成生成器
  • 函数时按照顺序执行,遇到return语句或者最后一行函数语句就返回。如果想让一个函数变为生成器函数,只需要将函数的return变为yield。
  • 变成generator函数,在每次调用next()函数的时候,遇到yield语句时返回,如果再次执行next()函数,会从上次返回的yield语句处继续执行
  • 生成器函数
def func2():
    print("tom is a good man")
    yield 2
    print("tom is a nice man")
    yield 3
    print("tom is a cool man")
    yield 4
    print("tom is a handsome man")
    yield 5
res2 = func2()
print(res2, type(res2))	#<generator object func2 at 0x0000000002655B48> <class 'generator'>
print("*",next(res2))	#tom is a good man
* 2
print("*",next(res2))	#tom is a nice man
* 3
print("*",next(res2))	#tom is a cool man
* 4
print("*",next(res2))	#tom is a handsome man
* 5
def func3():
    for i in range(1, 11):
        num = i * i
        yield num
res3 = func3()
print([i for i in res3])	#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

迭代器

  • 概述:
    1、可以被next()调用并返回一个值的对象称为Iterator
    2、迭代器不但可以用作for循环,还可以被next()调用
  • 可迭代对象转迭代器
li = [1,2,3,4,5]
li = iter(li)
print(li, type(li))
<list_iterator object at 0x00000000026ABF28> <class 'list_iterator'>
  • 为什么list、tuple、dict、set、string等数据类型不是Iterator
  • Iterator对象表示的是一个数据流,Iterator可以被next()函数调用并返回一个数据,直到抛出StopIteration错误。可以把数据流看成一个有序的序列,但是不去定这个序列的长度,只能通过next()函数不断计算下一个数据,所以说Iterator的设计是惰性求值。Iterator可以表示一个无限大的数据流,而list永远不可能存储无限的数据

生成器的经典案例

  • 生成器实现斐波那契数列
#编写函数实现斐波那契数列
def fib1(count=1):
    li = []
    x, y = 0, 1
    for i in range(5):
        li.append(y) # 1  1  2   3
        x, y = y, x + y
    return li
li1 = fib1(5)  #[1,1,2,3,5]
print(li1)

# 生成器实现
def fib2(count=1):
    x, y = 0, 1
    for i in range(5):
        yield y# 1  1  2   3
        x, y = y, x + y
     return "hello world"
g = fib2(5)
for i in g:
    print(i)  #[1,1,2,3,5]
#for循环遍历generator时拿不到generator的返回值的值
#如果想拿返回值,必须捕获StopIteration异常,返回值包含在错误对象value属性中
while 1:
    try:
        res = next(g)
        print(res)
    except StopIteration as e:
        print("返回值:", e.value)
        break
  • 杨辉三角
#函数实现
def func(n):
    arr = [1]
    for i in range(n):
        print(arr) #[1,3,3,1]
        arr = [arr[x] + arr[x+1] for x in range(len(arr)-1)]# 012   [1,4,6,4,1]
        arr.insert(0, 1)
        arr.append(1)
func(5)
#生成器实现
def func(n):
    arr = [1]
    for i in range(n):
        yield arr #[1,3,3,1]
        arr = [arr[x] + arr[x+1] for x in range(len(arr)-1)]# 012   [1,4,6,4,1]
        arr.insert(0, 1)
        arr.append(1)
g = func(10)
for i in g:
    print(i)
'''
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
'''

偏函数

  • 作用:固定调用函数时某个参数的值,不用显示的传递
  • int():将字符串转为数字,默认按十进制转换,可以设置进制
print(int("123"))
print(int("123a", base=16)) #指定为16进制
#4666      将123a转为十进制的数

#解决:类似偏函数
def int16(str, base=16):
    return int(str, base=base)
print(int16("123a"))

#偏函数解决
import functools
in16 = functools.partial(int, base=16)
print(in16("123a"))

最后

以上就是魁梧枫叶为你收集整理的python的函数认识函数的全部内容,希望文章能够帮你解决python的函数认识函数所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部