python 高级特性_生成式&生成器与迭代器&闭包&装饰器&内置高阶函数

本文详细介绍了Python的高级特性,包括生成式、生成器、迭代器与可迭代对象的关系,深入讲解了生成式在列表、集合、字典中的应用,以及生成器的创建、访问、yield关键字的用法。此外,还探讨了闭包、装饰器的概念、应用场景及实现方式,最后提到了内置高阶函数map、reduce、filter和sorted的用法和区别。
摘要由CSDN通过智能技术生成

python 高级特性

学习目标

1、生成式详解
2、生成器与yield详解
3、生成器、迭代器与可迭代对象
4、闭包
5、装饰器
6、内置高阶函数

一、 生成式详解

最快生成列表、集合、字典的公式

列表生成式
就是一个用来生成列表的特定语法形式的表达式。是Python提供的一种生成列表的简洁形式, 可快速生成一个新的list。
• 普通的语法格式:[exp for iter_var in iterable]
• 带过滤功能语法格式: [exp for iter_var in iterable if_exp]
• 循环嵌套语法格式: [exp for iter_var_A in iterable_A for iter_var_B in iterable_B]

字典生成式:
用来快速生成字典;
集合生成式:
用来快速生成集合;

1.1.1 列表生成式(普通)示例:

在这里插入图片描述
在这里插入图片描述

1.1.2 列表生成式(过滤)示例:

在这里插入图片描述
在这里插入图片描述

1.1.3 列表生成式(嵌套)示例:

在这里插入图片描述

1.2 集合生成式示例:

在这里插入图片描述

1.3 字典生成式示例:

在这里插入图片描述

2. 生成式练习题:

1). 求以r为半径的圆的面积和周长(r的范围从1到10)。

import math

def circle_example():
    """求以r为半径的圆的面积和周长(r的范围从1到10)。"""
    square = lambda r: math.pi * (r ** 2)
    C = lambda r: 2 * math.pi * r
    return [(square(r), C(r)) for r in range(1, 11)]

if __name__ == '__main__':
    result=circle_example()
    print(result)

2). 将字典的key值和value值调换。

def swap_key_value(dictObj):
    """将字典的key值和value值调换"""
    return {
   value: key for key, value in dictObj.items()}

if __name__ == '__main__':
    d = {
   
        'user1': 'passwd1',
        'user2': 'passwd2',
    }
    result2 = swap_key_value(d)
    print(result2) #{'passwd1': 'user1', 'passwd2': 'user2'}

3). 找出1~100之间所有的质数。

def is_prime(num):
    """判断num是否为质数?如果是,返回True, 否则返回False. 具体的代码自行补充完整"""
    for i in range(2,num):
        if num%i==0:
            return False
    else:
        return True
def find_prime():
    """找出1~100之间所有的质数"""
    return [num for num in range(1, 101) if is_prime(num)]

if __name__ == '__main__':
    result3=find_prime()
    print(result3)
    #[1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

4). 字典key值大小写计数合并 : 已知字典{‘A’:10, ‘b’:5, ‘a’:2}, 合并后为{‘a’:12, ‘b’:5}。注意: key值最终全部为小写.

def value_add():
    '''字典key值大小写计数合并 : 已知字典{'A':10, 'b':5, 'a':2}, 合并后为{'a':12, 'b':5}。注意: key值最终全部为小写.'''
    d = {
   'a':2, 'b':1, 'c':2, 'B':9, 'A':10}
    return {
   key.lower():(d.get(key.lower(),0)+d.get(key.upper(),0)) for key in d.keys()}
if __name__ == '__main__':
    result4=value_add()
    print(result4) #{'a': 12, 'b': 10, 'c': 2}

二、 生成器详解

1.定义和特点

1)什么叫生成器?
在Python中,一边循环一边计算的机制,称为生成器:Generator。
生成器仅仅保存了一套生成数值的算法,并且没有让这个算法现在就开始执行,而是我什么时候调它,它什么时候开始计算一个新的值,并给你返回。

2)什么时候需要使用生成器?
性能限制需要用到,比如读取一个10G的文件,如果一次性将10G的文件加载到内存处理的话(read方法),内存肯定会溢出;但使用生成器把读写交叉处理进行,比如使用(readline和readlines)就可以再循环读取的同时不断处理,这样就可以节省大量的内存空间.

3)生成器的特点是什么?
• 解耦. 爬虫与数据存储解耦;
• 减少内存占用. 随时生产, 即时消费, 不用堆积在内存当中;
• 可不终止调用. 写上循环, 即可循环接收数据, 对在循环之前定义的变量,可重复使用;
• 生成器的循环, 在 yield 处中断, 没那么占 cpu.

2.生成器的创建和访问

1)如何创建生成器?
第一种方法: 列表生成式的改写。 []改成()
第二种方法: yield关键字。

2)如何打印生成器的每一个元素呢?
通过for循环, 依次计算并生成每一个元素。
如果要一个一个打印出来,可以通过next()函数获得生成器的下一个返回值。

第一种方法: 列表生成式的改写。 []改成()

# 生成器创建
nums_gen = (num for num in range(1, 10001) if num % 8 == 0)
print(nums_gen)             # <generator object <genexpr> at 0x7f8f2cb92350>
print(type(nums_gen))       # <class 'generator'>

# 查看一个对象是否可以for循环?
from collections.abc import  Iterable
print("生成器是否为可迭代对象?", isinstance(nums_gen, Iterable))

# 访问生成器对象元素的方法一: 通过for循环, 依次计算并生成每一个元素。
"""
for num in nums_gen:
    if num > 50:
        break
    print(num)
"""

# 访问生成器对象元素的方法二: 如果要一个一个打印出来,可以通过next()函数获得生成器的下一个返回值。
print(next(nums_gen))       # 执行一次next生成一个值
print(next(nums_gen))
print(next(nums_gen))

注意:

在这里插入图片描述

第二种方法: 函数中包含yield关键字

Fib数列的案例理解生成器的创建
"""
def fib1(num):
    """递归实现Fib数列"""
    if num in (1, 2):
        return 1
    return fib1(num - 1) + fib1(num - 2)
"""
# 第二种方法: 函数中包含yield关键字
def fib2(num):
    """不使用递归方式实现Fib数列"""
    count = 0
    a = b = 1
    while True:
        if count < num:
            count += 1
            yield a
            a, b = b, a + b
        else:
            break
# 如果函数中有yield关键字, 那么函数的返回值是生成器对象.
result = fib2(100)
print(result)  #<generator object fib2 at 0x000002167FCD7660>

# 访问生成器对象元素的方法一: 通过for循环, 依次计算并生成每一个元素。
"""
for num in result:
    if num > 50:
        break
    print(num)
"""
结果:
1
1
2
3
5
8
13
21
34


# 访问生成器对象元素的方法二: 如果要一个一个打印出来,可以通过next()函数获得生成器的下一个返回值。
print(next(result))       # 执行一次next生成一个值   #1
print(next(result))                                #1
print(next(result))                                #2

3. python中return关键字和yield关键字的区别?

return:

函数遇到return, 函数旧执行结束。 后面的代码不会执行的。

def return_example():
    print('step 1')  #执行
    # 函数遇到return, 函数旧执行结束。 后面的代码不会执行的。
    return True
    print('step 2')  #不执行
yield:

理解yield的工作原理:
函数中包含yield关键字, 返回的是生成器对象。
当第一次调用next(genObj), 才执行函数内容.
遇到yield关键字, 执行停止。
再次调用next方法时, 从上词停止的代码位置继续执行。
遇到yield关键字, 执行停止。

def yield_example():          
    for count in range(100):  # 3  # 7
        yield 'step' + str(count + 1)   # 4 停止  # 8 停止
        print("success")      # 6   从上次停止的地方开始执行

if __name__ == '__main__':
   result = yield_example()   # 1 
   print(next(result))        # 2 执行函数yield_example
   print(next(result))        # 5 

结果:
step1
success
step2

4.生成器的send方法

给生成器传递数据&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值