python学习笔记:推导式,生成器,迭代器

推导式

列表推导式

将旧的列表通过推导产生新的符合需求的列表
格式:

[表达式 for 变量 in 旧列表]
[表达式 for 变量 in 旧列表 if 条件]  # 遍历旧列表元素,对于旧列表中取出的每一个元素(赋值给了for后的变量)若此变量符合条件,则将此变量传递给前方表达式,由表达式处理后加入待返回的列表中.
[表达式1 if 条件 else 表达式2 for 变量 in 列表] # 对旧列表中的每一个元素((赋值给了for后的变量) 若其满足条件,则执行表达式1,否则执行表达式2 ,将执行结果加入新列表中

注:for-in-if结构可以在中括号中存在多个,前方的表达式中的变量需要与for中的变量对应一致
例如:

# 获取以1到1000的整数为元素的列表
res = [i for i in range(1001)]

# 获取列表中长度小于等于3的字符串
names = ['mike', 'jack', 'john', 'kai']
res = [name for name in names if len(name) <= 3]
print(res)  # ['kai']

# 获取列表中长度大于3的元素,并将其首字母改为大写
names = ['mike', 'jack', 'john', 'kai']
res = [i.capitalize() for i in names if len(i) > 3]
print(res)  # ['Mike', 'Jack', 'John']

# 获取1~100中可被3整除的元素组成的列表
res = [i for i in range(101) if i % 3 == 0]
print(res)

# 获取一个列表,其元素为还有两个元素的元组,每个元组的第一个元素为5以内的偶数,第二个元素为10以内的奇数
res = [(x, y) for x in range(1,5) if x % 2 == 0 for y in range(1,10) if y % 2 != 0]
print(res)

# 某列表re的元素为含有三个元素的列表,获取列表中各个子列表的最后一个元素组成的列表
res2 = [a[-1] for a in re]
print(res2)

# 某列表中元素为字典,各个字典中存储学生信息,若学生年龄少于18,则年龄加2,否则减3

集合推导式

格式:

{表达式 for 变量 in iterable}
{表达式 for 变量 in iterable if 条件}

如:

# 将列表中的重复元素去除.
lists = [1, 2, 3, 1, 6, 88, 2, 3]
res = {i for i in lists}
print(res)

字典推导式

格式:

{表达式1:表达式2 for 变量列表 in 旧字典}
# for 之前的格式必须为以冒号分隔的两个值的形式
# 颠倒字典中的键与值
res = {value : key for key, value in dicts.items()}
print(res)

生成器 generator

受内存的限制,列表的容量有限,当列表的元素数量十分巨大时(如里列表中有上百万个元素),若仅使用此种列表的前部少数几个元素,会消耗很多系统资源.
因此若列表中的元素可以按照一定的算法推算出来,则可不必创建完整的列表.
在Python中,一边循环一边计算的机制称作生成器

创建方式

  1. 通过列表推导式创建生成器
    (列表生成式)  # 括号中的内容不包括列表生成式的中括号
    
    例:
    gen = (x for x in range(100000))
    print(type(gen))  # <class 'generator'>
    print(gen)  # <generator object <genexpr> at 0x0000024779212DD0>
    
  2. 通过函数创建生成器
    步骤:
    • 创建函数并在返回数据时使用关键字yield(其表示返回并暂停)
    • 调用此函数并用一变量接收此函数(接收后此变量即为生成器类型)
    • 使用生成器的相关函数获取值
      例:
    def generate(): # 定义生成器
        n = 0
        while True:
            n += 1
            yield n # 使用关键字 yield 
    
    g = generate()
    print(type(g))  # <class 'generator'>
    
    # 斐波那契数列
    def fib():
        a, b = 0, 1
        while True:
            yield b
            a, b = b, a + b
        
    g = fib()
    print(next(g))
    print(next(g))
    
    注:
    • 当使用函数方式获取生成器时,获取下一个元素后会暂停在yield之后,再次获取下一个元素时会在yield之后继续执行.
    • 函数方式的生成器可以带有return 语句,但只在生成器中元素取尽之后才会执行,可以用来提示元素取尽

从生成器中获取值

  1. 使用生成器内置函数.__next__()
    例:
    gen = (x for x in range(100000))
    gen_next = gen.__next__()
    print(gen_next)  # 0
    
  2. 使用系统内置函数next(iterable, default)
    参数描述
    iterable必需。可迭代对象。
    default可选。在迭代结束时返回的默认值。
    注:若以获取了生成器中所有值,且未指定默认值,再次调用此方法则会报错
    例:
    gen = (x for x in range(100000) if x % 3 ==0)
    gen_next = next(gen)
    print(gen_ne)  # 0 
    gen_next = next(gen)
    print(gen_ne)  # 3 
    gen_next = next(gen)
    print(gen_ne)  # 6 
    
    # 获取生成器中所有元素
    ## 使用循环来实现
    ### ∵若不指定默认值,元素取尽后会报错 ∴需要进行异常处理
    #### 指定默认值
    gen = (x for x in range(100) if x % 3 == 0)
    while True:
        i = next(gen, '')
        if i == '' :
            break
        print(i)
    
    #### 不指定默认值
    gen = (x for x in range(100) if x % 3 == 0)
    while True:
        try:
            i = next(gen)
            print(i)
        except:
            print('值已取尽!')
            break
    

内置函数send(value)

此函数有一个参数value,该参数指定的是上一次被挂起的yield语句的返回值.
调用此函数会返回yield语句产生的值,并将参数传入生成器函数,将其作为yield语句的返回值.
可以在生成器函数中借助此值控制生成器的执行
注:第一次使用此函数需要传入None.

def fib():
    i = 0
    while i < 5:
        temp = yield i
        print('temp', temp)
        i += 1
    return 'end'

g = fib()
n0 = g.send(None)   #1
print('n0', n0)     #2
n1 = g.send('haha') #3
print('n1', n1)     #4
n2 = g.send('hehe') #5
print('n2', n2)     #6
'''
打印结果:
n0 0  # 此句为执行语句2的结果,之前的语句1执行后将yield语句产生的0赋给变量n0
temp haha  #此句为执行语句3的结果,其参数haha指定为语句1调用后的yield语句的返回值,继续执行后,被赋给变量temp,后执行打印语句打印此值,追后执行到第二次yield语句,将值1返回并赋给变量n1
n1 1
temp hehe
n2 2
'''

生成器的应用–多任务—协程

将一个线程分为若干份,每份为一个协程.
在函数的相应位置添加关键字yieldyield None 使其成为生成器函数,

# 函数1和函数2交替执行
def fun1(n):
    for i in range(n):
        print('AAAAAAA', i + 1)
        yield

def fun2(n):
    for i in range(n):
        print('BBBBBBB', i + 1)
        yield

g1 = fun1(3)
g2 = fun2(5)
while True:
    try:
        g1.__next__()
        g2.__next__()
    except:
        pass
'''
结果
AAAAAAA 1
BBBBBBB 1
AAAAAAA 2
BBBBBBB 2
AAAAAAA 3
BBBBBBB 3
'''

迭代器

可迭代的对象

  1. 生成器
  2. 列表,元组,集合,字典,字符串
  • 判断是否可迭代
    使用系统内置函数isinstance(object, type),将参数type指定为Iterable(需要先引入typing中的Iterable, from typing import Iterable)
    from typing import Iterable
    
    a = (x for x in range(10))
    res = isinstance(a, Iterable)
    print(res)
    

迭代器

  • 定义:可以被next()函数调用并不断返回下一个值的对象称为迭代器.
  • 迭代是访问集合元素的一种方式,迭代器时一个可以记住遍历位置的对象,
  • 迭代器对象从集合或列表的第一个元素开始访问,直到所有元素访问结束.
  • 迭代器只可向前不可向后.
  • 可迭代的未必是迭代器(如list不是迭代器),
  • 系统内置函数iter(object, sentine)返回迭代器对象,将可迭代的变为迭代器
    参数描述
    object必需。可迭代对象。
    sentine可选。如果对象是可调用对象,则当返回值与前哨相同时,迭代将停止。
    l = [1, 2, 3, 4, 5]
    i = iter(l)
    next1 = next(i)
    print(next1)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值