day12-高阶函数和迭代器生成器

1.函数作为变量

1)函数就是变量

python中声明函数其实就是声明一个类型是function的变量,函数名就是变量名;变量能做的函数都能做

a = 10
def func1():
    return '=='
def func2():
    return '====='
print(id(a), id(func1))
print(type(a), type(func1))
# 1.变量可以给别的变量赋值
b = a
c = func1
print(c())
# 2.重新给变量赋值
a = 'abc'
func1 = 100
print(func1*2)
func1 = func2
# 3.变量作为容器类型数据的元素
list1 = [a, 10, func1]
print(list1)
print(list1[-1]())
# 4.变量作为函数的参数
def func3(num):
    sum1 = num ** num
    return sum1
print(func3(3))
a = 4
print(func3(a))
# 函数作为函数的参数  - 实参高阶函数
def func4(fn):
    fn()
def func5(x=10):
    print(x)
func4(func5)

2)系统实参高阶函数:列表.sort\sorted\max\min...中有个参数key,类型就是function。

key的用法:
key是一个函数,必须有且只有一个参数(代表序列中的元素),还有一个返回值(返回值就是比较标准)

students = [
    {'name': 'a', 'age': 22, 'score': 99},
    {'name': 'b', 'age': 20, 'score': 29},
    {'name': 'c', 'age': 24, 'score': 86},
    {'name': 'd', 'age': 17, 'score': 44}
]
def test(x):
    print(x)
    return x['age']
students.sort(key=test)
print(students)
# 练习:将列表nums中所有元素按各位数的和从小到大排序
nums = [19, 29, 54, 81, 75, 23]
def test1(item):
    print(item)
    sum1 = 0
    for x in str(item):
        sum1 += int(x)
    return sum1
nums.sort(key=test1)
print(nums)
# max的原理
def ysy_max(seq, key=None):
    if key:
        list1 = list(seq)
        max1 = list1[0]
        for item in list1[1:]:
            if key(item) > key(max1):
                max1 = item
        return max1
    else:
        list1 = list(seq)
        max1 = list1[0]
        for item in list1[1:]:
            if item > max1:
                max1 = item
        return max1
print(ysy_max([12, 34, 52]))
print(ysy_max('1d2s1'))
print(ysy_max({'name': 'a', 'age': 12}))
print(ysy_max([13, 12, 44], key=lambda item: item % 10))
# 5.变量作为函数的返回值
# 函数作为函数的返回值(返回值高阶函数)
def operation(char):
    if char == '+':
        def sum1(*nums):
            x = 0
            for num in nums:
                x += num
            return x
        return sum1
    elif char == '*':
        def sum2(*nums):
            x = 1
            for num in nums:
                x *= num
            return x
        return sum2
print(operation('+')(12, 90, 22))

2.装饰器

1)什么是装饰器

装饰器的本质就是函数,是用来给函数添加功能用的

装饰器 = 实参高阶函数 + 返回值高阶函数 + 糖语法

# 实例一:给函数添加功能(统计执行时间的功能)
def func1(x, y):
    print(x + y)
func1(10, 20)
def func2():
    print('   *')
    print('====')
func2()
# 实例二:用实参高阶函数给不同的函数添加相同功能
def statistics_time(fn, *args, **wkargs):
    t1 = time.time()
    fn(*args, **wkargs)
    t2 = time.time()
    print('时间:{}s'.format(t2 - t1))
statistics_time(func1, y=1, x=2)
# 实例三:无参装饰器
"""
a.语法
def 函数1(fn):
    def 函数2(*args, **kwargs):
        实现添加功能的代码
        fn(*args, **kwargs)
    return 函数2
b.说明:
函数名1 - 装饰器的名字(根据添加的功能来命名)
fn  - 类型是函数,指向的是需要添加功能的函数
函数名2 - 实现添加功能的函数,名字随便命名,一般为test 
"""
def add_time(fn):
    def test(*args, **kwargs):
        t1 = time.time()
        fn(*args, **kwargs)
        t2 = time.time()
        print(t2-t1)
    return test
@add_time
def func5():
    print('5')
func5()
# 实例四:有参装饰器
"""
有参装饰器的写法:
def 装饰器名(参数列表):
    def 函数名1(fn):
        def test(*args,**kwargs):
            fn(*args,**kwargs)
            添加新功能
        return test
    return 函数1
    
说明:参数列表 - 装饰器添加功能的时候变化的部分通过参数列表来确定
"""
def tag(name):
    def func11(fn):
        def test(*args, **kwargs):
            re_str = fn(*args, **kwargs)
            new_str1 = '<%s>' % name + re_str + '<%s>' % name
            return new_str1
        return test
    return func11
@tag(name='p')
def render(text):
    # 执行其他操作
    return text

练习1:写一些装饰器,实现函数结束调用结束后打印‘调用完成’

def add_print(fn):
    def test(*args, **kwargs):
        fn(*args, **kwargs)
        print('调用完成')
    return test
@add_print
def func6(m):
    print(m**2)
func6(8)

练习2:写一个装饰器,实现将返回值是整数的函数的返回值以十六进制的形式返回

def hex_result(fn):
    def test(*args, **kwargs):
        re = fn(*args, **kwargs)
        return hex(re)
    return test
@hex_result
def func7(m):
    return m ** 2
print(func7(2))

3.迭代器

1)什么是迭代器(iter)

迭代器是容器型数据类型(序列),迭代器中的元素只能通过将其他序列转换成迭代器或者创建生成器
迭代器中的元素:如果需要查看元素,需要将元素从迭代器取出,而且一旦取出就不能再放回去

2)创建迭代器

iter(序列) - 将序列转换成迭代器并返回

iter1 = iter('akq')
print(iter1)

iter2 = iter({'name': 'a', 'age': 19})
print(iter2)

3)获取元素

1)获取单个元素
next(迭代器) / 迭代器.next()

item = next(iter2)
print(item)        # name
item = next(iter2)
print(item)        # age
# item = next(iter2)
# print(item)        # 报错:StopIteration

2)遍历迭代器

print('======')
for x in iter1:
    print('x:', x)
    
# 练习:
iter1 = iter('hello')
list1 = list(iter1)
print(list1)   # ['h', 'e', 'l', 'l', 'o']
# print(next(iter1))   # 报错:StopIteration

4.生成器

1)什么是生成器

生成器就是迭代器,容器有产生数据的能力。

1)怎么创建生成器:调用一个带有yield关键字的函数,就可以得到一个生成器对象

2)生成器产生数据的原理:
当调用一个带有yield关键字函数的时候,不会执行函数体,也不会获取返回值,而是创建一个生成器;
生成器能产生多少个数据,以及每个数据的值,看执行完函数体会遇到几次yield生成器就可以产生几个数据,
yield后面的数据就是会产生的数据
每次获取生成器的元素的时候,都会去执行相应的函数的函数体,执行到yield为止,取下一个元素,
从上次结束的位置接着往后执行

def func1():
    print('=====')
    print('+++++')
    yield [8, 9]
    print('----')
    yield 4
re = func1()
print('re:', re)
print(next(re))
print('第一次结束')
print(next(re))

练习:写一个学号生成器,能够产生的学号的范围和学号的前缀创建生成器的时候自己决定

def creat_id(pre, num):
    length = len(str(num))
    for x in range(num):
        yield pre+str(x).zfill(length)
py_creater = creat_id('python', 200)
print(next(py_creater))

5.生成式

1)什么是生成式

生成式就是生成器的一种简写方式

1)形式一:
(表达式 for 变量 in 序列) - 序列有多少个元素,生成器就能产生多少个数据,每次循环表达式的值就是产生数据的值

相当于:
def func1():
for 变量 in 序列:
yield 表达式

2)形式二:
(表达式 for 变量 in 序列 if 条件语句)

def func1():
for 变量 in 序列:
if 条件语句:
yield 表达式

gen1 = (x*2 for x in range(5))
print(gen1)
print(next(gen1), next(gen1))

gen2 = (x*2 for x in range(5) if x % 2)
print(next(gen2))

2)变形

1)列表生成式
[表达式 for 变量 in 序列] 相当于 list((表达式 for 变量 in 序列))
[表达式 for 变量 in 序列 if 条件语句]

2)集合生成式
{表达式 for 变量 in 序列} 相当于 set((表达式 for 变量 in 序列))
{表达式 for 变量 in 序列 if 条件语句}

3)生成式转字典
dict(表达式 for 变量 in 序列)

list1 = [x*2 for x in range(5)]
print(list1)
list2 = [x*2 for x in range(5) if x % 2]
print(list2)
set2 = {x*2 for x in range(5) if x % 2}
print(set2)

dict1 = dict((x*2, x) for x in range(5) if x % 2)
print(dict1)

练习:用一行代码实现交换一个字典的键对,产生新的字典

dict2 = {'a': 1, 'b': 2, 'c': 3}
new_dict2 = dict((dict2[key], key) for key in dict2)
print(new_dict2)

你可能感兴趣的:(day12-高阶函数和迭代器生成器)