学习笔记-python生成器、迭代器、可迭代

学习笔记-python生成器、迭代器、可迭代

一、生成器

在Python中,一边循环一边计算的机制,称为生成器:generator
列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。

如:仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

如果列表元素按照某种算法推算出来,那我们就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。

简单一句话:我又想要得到庞大的数据,又想让它占用空间少,那就用生成器!
生成器概念
生成器的创建可以通过关键字yield
获取生成器的元素可以通过:next(生成器) 、生成器.next()、生成器.send(传参)
1、创建一个生成器

创建生成器的方式有两种:

  1. 一种是通过推导式的方式创建生成器;
  2. 一种是通过函数中添加关键字yield的方式创建生成器

使用函数中添加yield关键字创建生成器需要注意:

  1. 需要先定义函数,在函数中需要使用关键子yield,调用函数得到一个生成你对象,再结合next
  2. 只要遇到yield则回i爱你搞起后面值返回并暂停,下次执行时,从该位置开始
  3. 一个函数中可以有多个yield
  4. 如果函数有返回值,返回值的内容会作为生成器元素取完后报错的内容:StopIteration:生成器函数返回值
g = (x for x in range(1,3))     # 通过推导式生成一个生成器
print(type(g))
print(next(g))
t = next(g)
print(next(g, 0))       # 配置默认值为0,当next最后一个值时将会报错,设置默认值将不会报错

from collections import  Iterable, Iterator
import types
print(isinstance(t, Iterable))      # 判断是否为可迭代的
print(isinstance(t, Iterator))      # 判断是否为迭代器
print(isinstance(g, types.GeneratorType))   # 判断是否为生成器


def func():							# 通过函数中yield关键字的方式创建
    for i in range(1, 3):
        yield i             # 类似于return和暂停,下次next时从这个位置开始
        print('i:{}'.format(i))
        yield "ok"          # 一个函数中可以有多个yield

f = func()
print(next(f))			
print(f.__next__())     # 同next(f)
print(next(f))

2、为生成器中传参
为生成器中传参可以使用send()方法来进行,在传参时需要注意:
第一个值需要先传None,否则会报错,后面可根据生成器传参

def func1():				# 创建一个生成器对象
    for i in range(1, 3):
        x = yield i             # 类似于return和暂停,下次next时从这个位置开始,这里的x就是send方法传递的参数
        s = x + 10
        print("s:{}".format(s))

print("*"*40)
f1 = func1()
# print(next(f))
print(f1.send(None))           # 第一个值需要先传None
print(f1.send(10))

3、使用生成器创建斐波拉契数列

def func2(n):
    a, b = 0, 1
    for i in range(n):
        yield b
        a, b =b, b+a
    return "over"

f2 = func2(4)
try:
    while True:
        print(f2.__next__())
except StopIteration as e:		# 接收报错
    print(e)

4、生成器在多任务切换时应用

def test1():			# 创建生成器
    for i in range(1, 5):
        print("this is test1 {}".format(i))
        yield

def test2():
    for i in range(1, 5):
        print("this is test2 {}".format(i))
        yield

def test3():
    for i in range(1, 5):
        print("this is test3 {}".format(i))
        yield

t1 = test1()			# 创建生成器对象
t2 = test2()
t3 = test3()

try:				# 取出生成器中的元素
    while True:
        t1.__next__()
        t2.__next__()
        t3.__next__()
except StopIteration:
    pass

二、可迭代的

概念:
Python中的迭代是指通过重复执行的代码处理相似的数据集的过程,并且本次迭代的处理数据要依赖上一次的结果继续往下做,上一次产生的结果为下一次产生结果的初始状态,如果中途有任何停顿,都不能算是迭代。
可迭代对象有:列表、元组、字典、字符串
判断一个对象是不是可迭代的可以同下面方式

from collections import  Iterable
print(isinstance(对象, Iterable))      # 判断是否为可迭代的
# 如果输出为True表示为可迭代,False则表示不可迭代

三、迭代器

概念:
迭代,顾名思义就是重复做一些事很多次(就现在循环中做的那样)。迭代器是实现了__next__()方法的对象(这个方法在调用时不需要任何参数),它是访问可迭代序列的一种方式,通常其从序列的第一个元素开始访问,直到所有的元素都被访问才结束。 [注意]:迭代器只能前进不能后退
[迭代器的优点]:
使用迭代器不要求事先准备好整个迭代过程中的所有元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后元素可以不存在或者被销毁。因此迭代器适合遍历一些数量巨大甚至无限的序列。
判断一个对象是否为迭代器

from collections import  Iterator
print(isinstance(对象, Iterator))      # 判断是否为迭代器
# 如果输出为True表示为迭代器,False则表示不是迭代器

可迭代的转迭代器

可以通过iter()函数来转换,注意:

  1. 转换后的对象为迭代器
  2. 转化后获取元素需要通过next()来获取
  3. 转换后无法像之前一样通过print查看所有元素
from collections import  Iterable, Iterator
list1 = ['w', 'c', 'g']
print(isinstance(list1, Iterator))   	# False
list2 = iter(list1)	
print(isinstance(list2, Iterator))		# True

可迭代的、迭代器、生成器的关系
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值