迭代器和生成器

可迭代对象和迭代器

基础概念

  • 所有的可迭代对象均内置了_iter_()方法,调用iter()方法,返回值就是一个迭代器
  • 迭代器中内置了_next_()方法,调用该方法,会返回迭代器对象的每个元素,因此迭代就是从迭代器中取元素的过程
  • python中的列表、字典、元组、字符串都是可迭代对象,可迭代对象都可以用for循环实现迭代遍历。
判断
from collections.abc import Iterable, Iterator
a = [1, 2, 3]
b = iter(a) # 可迭代对象调用内置iter()方法返回一个迭代器
isinstance(a, Iterable)
isinstance(b, Iterator)
isinstance(b, Iterable)
for循环本质

调用可迭代对象的_iter_()方法,得到该对象对应的迭代器对象,然后无限调用_next_()方法,得到对象中的每一个元素,直到Stopiteration异常,代表迭代器中已无下一个元素,for循环自动处理该异常,跳出循环。

# 字典的键,值,键值对都是可迭代对象
for key in {'one':1, 'two':2}:
print(key)
# 字符串是可迭代对象
for char in "123":
print(char)
# 打开的text同样是可迭代对象
for line in open("myfile.txt"):
print(line, end='')
不想用for循环迭代了,如何使用迭代器?
  1. 先调用容器(以字符串为例)的iter()函数
  2. 再使用 next() 内置函数来调用 __next__() 方法
  3. 当元素用尽时,__next__() 将引发 StopIteration 异常

列表推导式
  • 用 []
li = [i for i in range(10)]
print(li)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 每个元素在生成后都会存在内存中,如果元素很多,就会占用很大的存储空间

迭代器实现一个列表:[i for i in range(1000)],

生成器Generator

概念

在Python中,我们把一边循环一边计算的机制,称为生成器。生成器也是一种迭代器,但由于它们并没有把所有的值存在内存中,而是在运行时生成值,因此只能迭代一次。

如何实现和使用?

1.生成器表达式

  • 用()
ge = (i for i in range(10))
print(li)
# <generator object <genexpr> at 0x7f4f446a21d0>
next(ge)
# 0
  • 生成器表达式可以认为是一种特殊的生成器函数,返回生成器对象,一次只返回一个值

2.带有关键字yield的函数

  • 程序运行到yied这一行的时候,生成器调用next()函数生成一个值,同时暂停程序,直到下次调用next()函数时才激活,从上次离开的位置恢复执行
def reverse(data):
for index in range(len(data)):
yield data[index]
print("大大")
# reverse('golf'), 此条语句返回一个生成器对象(也是可迭代对象),for循环实现遍历没毛病
for char in reverse('golf'):
print(char)
# 输出
g
o
l
f
大大
# 遍历方法2
char = reverse('golf') # 返回一个生成器对象,<generator object reverse at 0x7f71c8124250>
print(next(char))
print(next(char))
print(next(char))
print(next(char))
print(next(char))
# 输出
g
o
l
f
大大
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)

生成器,迭代器,可迭代对象之间的关系

  • 容器(列表,元组,字典,集合)是可迭代对象,可迭代对象调用 iter() 函数,可以得到一个迭代器。迭代器可以通过 next() 函数来得到下一个元素,从而支持遍历。
  • 生成器是一种特殊的迭代器(注意这个逻辑关系反之不成立)。使用生成器,你可以写出来更加清晰的代码;合理使用生成器,可以降低内存占用、优化程序结构、提高程序速度。

应用举例

1.给定一个list和一个指定数字,求这个数字在list中的位置
def index_normal(L, target):
result = []
for i, num in enumerate(L):
if num == target:
result.append(i)
return result print(index_normal([1, 6, 2, 4, 5, 2, 8, 6, 3, 2], 2)) # 使用生成器
def index_generator(L, target):
for i, num in enumerate(L):
if num == target:
yield i
# index_generator会返回一个生成器对象,需要使用list转换为列表后,才能print输出
print(list(index_generator([1, 6, 2, 4, 5, 2, 8, 6, 3, 2], 2)))
# 输出
[2, 5, 9]
2.给定两个序列,判定第一个是不是第二个的子序列

解析:序列就是列表,子序列指的是一个列表的元素在第二个列表中都按顺序出现,但是并不必挨在一起

def is_subsequence(a, b):
b = iter(b) # 把列表b转化成一个迭代器
return all(i in b for i in a)
# (i for i in a),将列表a初始化为一个生成器,可以遍历对象a
# i in b,判断生成器next()函数遍历a的指是否在迭代器b调用next()得到的对象中
# all函数,判断一个迭代器的元素是否全部为True print(is_subsequence([1, 3, 5], [1, 2, 3, 4, 5]))
print(is_subsequence([1, 4, 3], [1, 2, 3, 4, 5]))
# 输出
True
False
3.计算0-9数字的平方和
sum(i*i for i in range(10))
# 285

参考文章:

[1]https://zhuanlan.zhihu.com/p/76831058

[2]https://blog.csdn.net/baidu_28289725/article/details/80622454

[3]https://time.geekbang.org/column/article/101521?utm_source=pinpaizhuanqu&utm_medium=geektime&utm_campaign=guanwang&utm_term=guanwang&utm_content=0511

写在最后:

为了能把这篇笔记上传,分享出来,解决了困扰我的难题,那就是如何将本地的md格式的文件一键上传到博客园而不用粘贴复制呀?

推荐这个工具:

https://github.com/donghe123178/pycnblog

终于理解Python中的迭代器和生成器了!的更多相关文章

  1. python is、==区别;with;gil;python中tuple和list的区别;Python 中的迭代器、生成器、装饰器

    1. is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同 == 比较的是两个对象的内容是否相等 2. with语句时用于对try except finally 的优 ...

  2. python中的迭代器和生成器学习笔记总结

    生成器就是一个在行为上和迭代器非常类似的对象.   是个对象! 迭代,顾名思意就是不停的代换的意思,迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次“迭代”,而 ...

  3. Python中的迭代器和生成器

    本文以实例详解了python的迭代器与生成器,具体如下所示: 1. 迭代器概述: 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后 ...

  4. python中的迭代器与生成器

    迭代器 迭代器的引入 假如我现在有一个列表l=['a','b','c','d','e'],我想取列表中的内容,那么有几种方式? 1.通过索引取值 ,如了l[0],l[1] 2.通过for循环取值 fo ...

  5. Python中的迭代器、生成器

    from collections import Iterable, Iterator 1. 可迭代(iterable)对象 参考官网链接 class I: def __init__(self, v): ...

  6. Python中的迭代器、生成器、装饰器

    1. 迭代器  1 """ 2 iterator 3 迭代器协议: 对象必须提供一个next()方法,执行该方法要么返回迭代中的下一项,要么引起一个StopIterati ...

  7. python 中的迭代器和生成器简单介绍

    可迭代对象和迭代器 迭代(iterate)意味着重复,就像 for 循环迭代序列和字典那样,但实际上也可使用 for 循环迭代其他对象:实现了方法 __iter__ 的对象(迭代器协议的基础). __ ...

  8. pytorch :: Dataloader中的迭代器和生成器应用

    在使用pytorch训练模型,经常需要加载大量图片数据,因此pytorch提供了好用的数据加载工具Dataloader. 为了实现小批量循环读取大型数据集,在Dataloader类具体实现中,使用了迭 ...

  9. python设计模式之迭代器与生成器详解(五)

    前言 迭代器是设计模式中的一种行为模式,它提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示.python提倡使用生成器,生成器也是迭代器的一种. 系列文章 python设计模 ...

随机推荐

  1. Markdown 主题修改

    加粗字体的颜色修改 strong, b{ color: #111111; } 斜体的颜色修改 em, i { color: #111111; } 高亮字体的背景颜色修改 #write mark { b ...

  2. SpringMVC+Mybatis初尝试

    一个月前简单学完了SpringMVC框架和Mybatis框架,一直没有使用过,今天主要用它做了个简单的学生管理系统,不过第一次用框架,实现的功能简单,比较low. 注:这里使用的数据库是SQLServ ...

  3. jQuery中ajax 跳入error的原因总结

    一个标准的jquery的ajax代码: $.ajax({ type: 'POST', url: 'getSecondClassification', data: {"sort2": ...

  4. MSSQL(DAC环境一下一些特殊的访问方式)

    MSSQL(在DAC环境下访问: 存储过程) Server name:      admin:计算机名\实例名                 or       admin:IP地址\实例名      ...

  5. (八)postman请求的form-data、x-www-form-urlencoded、raw、binary的区别

    原文链接:https://blog.csdn.net/jiadajing267/article/details/87883725 1.form-data 等价于http请求中的multipart/fo ...

  6. HTTP参数污染学习

    HTTP参数污染 --- HPP 参考: 参数污染漏洞(HPP)挖掘技巧及实战案例全汇总 视频内容 HPP,简而言之,就是给参数赋上多个值. 比如: https://www.baidu.com/s?w ...

  7. python中列表,元组,字符串 互相转换

    #-*-coding:utf-8-*- #1.字典dict = {'name': 'Zara', 'age': 7, 'class': 'First'} #字典转为字符串,返回:<type 's ...

  8. Mysql和Redis数据同步策略

    为什么对缓存只删除不更新 不更新缓存是防止并发更新导致的数据不一致. 所以为了降低数据不一致的概率,不应该更新缓存,而是直接将其删除, 然后等待下次发生cache miss时再把数据库中的数据同步到缓 ...

  9. 入门大数据---Flume 简介及基本使用

    一.Flume简介 Apache Flume 是一个分布式,高可用的数据收集系统.它可以从不同的数据源收集数据,经过聚合后发送到存储系统中,通常用于日志数据的收集.Flume 分为 NG 和 OG ( ...

  10. Python实用笔记 (18)面向对象编程——类和实例

    类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各 ...