python 生成式,迭代器,生成器

DAY 6. 生成式,迭代器,生成器

6.1 生成式

6.1.1 列表生成式
list = [index for index in range(10)]
6.1.2 字典生成式
dict = {
    'zhangsan': 10,
    'lisi': 12,
    'wangwu': 18
}
# 实现键值互换
dict = {k:v for v,k in dict.items() if k >= 12}
6.1.3 集合生成式
# 100以内的质数
set = {i for i in range(100) if i % 2 != 0}

6.2 生成器

生成式会创建一个列表(字典或集合),但无论是字典,列表还是集合,都不能保存一个无限长的序列,比如说全体自然数,当然我们一般不会用到这种序列,但哪怕是万位的序列,保存为列表或集合也是很占用空间的,加上一般情况下我们对一个序列的操作是一次性的,根本不需要保存,那有没有一种办法只有我们需要时才给我们数据,我们不需要时程序只保留“算法”呢?这就用到了生成器

创建生成器有两种办法,一种是类似于推导式,把列表推导式的中括号改为小括号就行,会返回一个生成器对象,可以使用next()或for循环遍历

t = (i for i in range(100) if i % 2 == 0)
for i in t:
    print(i)

举个栗子,斐波那契数列,每一项是前两项之和

一般情况

feibo = [1, 1]
for i in range(2,10000):
    feibo.append(feibo[i - 1] + feibo[i - 2])
print(feibo)

我们要做的只是要打印出来而已,没必要保存这么大的数组,这时我们可以用生成器

def feb(f, s, max):
    i = 0
    while i < max:
        f, s = s, f + s
        i += 1
        yield s

for i in feb(1, 1, 100):
    print(i)

生成器长得和函数一样,只不过return 变成了yield ,每当运行到yield后,程序就会阻塞,只有在调用该生成器的next()方法时才会从上次暂停的地方继续

def Demo():
    print(1)
    yield 1
    print(2)
    yield 2
    print(3)
    yield 3

demo = Demo()
next(demo)
next(demo)
next(demo)
next(demo)

# 1
# 2
# 3
# Traceback (most recent call last):
#   File "E:/xxxx/DAY6_1.py", line 45, in <module>
#     next(demo)
# StopIteration

当超出生成器范围时会抛出StopIteration异常,我们一般也不会使用next,for就是捕捉StopIteration异常遍历生成器的

for i in Demo():
    i

# 等价于

while(True):
    try:
        next(demo)
    except StopIteration:
        break

6.3 迭代器

6.3.1 可迭代对象

可以直接作用于for循环的对象统称为可迭代对象:Iterable,主要有两类,列表,元组,字典,集合等数据类型和生成器,可以使用isinstance()判断一个对象是否是Iterable对象。

6.3.2 迭代器

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。可以使用isinstance()判断一个对象是否是Iterator对象

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。把list、dict、str等Iterable变成Iterator可以使用iter()函数

你可能会问,为什么list、dict、str等数据类型不是Iterator?

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

6.4 总结

  • 生成式
生成式语法
列表生成式L = [i for i in range(100) if i % 2 ==0]
字典生成式k:v for k, v in dict.items() if k < 10
集合生成式S = {i for i in range(100) if i % 2 ==0}
  • 生成器

创建:
生成式方式和生成器函数
读取:
next()或for

  • 迭代器
可迭代对象能被for直接作用的对象
迭代器能用next()执行的可迭代对象

参考文章:

GitHub python面试题

廖雪峰的官方网站

python 生成器和迭代器有这篇就够了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Junebao

如果你碰巧财力雄厚的话...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值