一、迭代器

1、可循环的有哪些,即可用for语句或者while语句的数据类型有哪些?
  字符串(str)、列表(list)、元组(tuple)、字典(dic)、集合(set)、枚举类(enumerate)
  还有哪些非数据类型,但是可以循环的?
  range(10),   文件句柄:f = open('filename',mode='r',enconding='utf-8')
2、查看这些可循环的数据类型或者函数或者文件句柄
  都有哪些共同的东西:(求交集,想到集合(set)的操作了)。
  还要引入一个内置函数dir()
print(dir())
print(dir(' '))
  由返回结果可以看到,dir带参数时,返回该参数的属性、方法列表。
  不带参数时,返回当前范围内的变量、方法和定义的类型列表;
 # 先可以求list和str的交集方法了
str_method_li = set(dir(''))
list_method_li = set(dir([]))
res = str_method_li & list_method_li
print(res)
# 还是由很多共有的方法,加大力度
tuple_m_li = set(dir(()))
dic_m_li = set(dir({}))
range_m_li = set(dir(range(5)))
set_m_li = set(dir(set({1, 2, 3, 4})))
res = res & tuple_m_li & dic_m_li & range_m_li & set_m_li
print(res)
# 还是由很多,我们还是看一看交集中一个双下方法名:__iter__
# 补充说明一下“双下方法”:方法名中开头和结果都带有两个下滑线的,即叫双下方法!它是python中用C实现的方法!
# 这个__iter__, 跟可迭代对应的英文iterable很像!
我们可以得出结论:
只要是能被for循环的数据类型,就一定拥有__iter__方法!
print([].__iter__())
# 运行结果为:<list_iterator object at 0x000001C2AD37B4A8>
# 即得到list的迭代器对象,因此我们可以判断,该方法返回的是一个迭代器(iterator)!
iterator = 'lov'.__iter__()
print(dir(iterator))
# 看到迭代器中的方法中,有一个双下方法:__next__,我们来看看它得到的是什么?
print(iterator.__next__())
# 返回的是字符串中的第一字母,再执行一次!
print(iterator.__next__())
# 返回的是字符串中的第二字母,再执行一次!
print(iterator.__next__())
# 返回的是字符串中的第三字母,再执行一次!
#print(iterator.__next__()) # 报错 StopIteration
# 这说明迭代器可以一个一个取集合中的元素,只到没有时,抛出异常!
总结一下:
#Iterable 可迭代的 -- > __iter__ #只要含有__iter__方法的都是可迭代的
[].__iter__() 迭代器 -- > __next__ #通过next就可以从迭代器中一个一个的取值 延申一下:
只要含有__iter__方法的都是可迭代的 —— 可迭代协议
自定义一个类型,可以用来迭代
 from collections import Iterable
from collections import Iterator class A:
def __next__(self):pass
def __iter__(self):pass a = A()
print(isinstance(a, Iterable))
print(isinstance(a, Iterator))
结果都为True,说明该类即可被迭代,也是迭代器!
3、迭代器的概念
迭代器协议:内部含有__next__方法和__iter__方法的就是迭代器
小结一下:
迭代器协议和可迭代协议
可以被for循环的都是可迭代的
可迭代的内部都有__iter__方法
只要是迭代器 一定可迭代
可迭代的.__iter__()方法就可以得到一个迭代器
迭代器中的__next__()方法可以一个一个的获取值
我们可以推导一下, for循环其实就是在使用迭代器
  只有是可迭代对象的时候 才能用for
  当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代
4、迭代器的好处
  从容器中一个一个取值,会将所有的值取到;
  节省内存空间:
 迭代器不会在内存中再占用一大块内存;
  每次next,都会给我们一个新的

二、生成器函数

1、生成器的引入场景

#如果想要一个包含2百万个ILOVEU的字符串,如何取得?如此取只会得到最后一个def func():
for i in range(2000000):
i = 'ILOVEU%s'%i
return i print(func())

改进一下:

def generate_str():
li = []
for i in range(200):
s = 'ILOVEU No' + str(i) + ' '
# print(s)
li.append(s)
return ','.join(li) print(generate_str())
如此做的确可以生成一个包含200万个’ILOVEU No%d‘的字符串,
但是如此使用迭代器无优势!因为它一次性在内存中生成,浪费内存空间,而迭代器的优点恰恰是节省内存!

总结:

理清迭代器的原理,可以理解for循环的是如何工作的,另外可以对了解生成器做铺垫!
迭代器虽然有很多优点,如节省内存空间,但是不能满足我们的所有需求;
如果我们平时在写代码过程中,要产生大量的数据,又不希望一次性在内存中生成,而且还要处处使用它,基于此种情况,
必须有我们自己写的迭代器!它就是生成器!

2、生成器有两种表现形式:

  1)、生成器函数 --- 本质上就是我们自己写的函数
  2)、生成器表达式

3、生成器函数的定义:

    只要含有yield关键字的函数都是生成器函数
 ef generator():
print(1)
#return 'a'
yield 'b' # yield不能和return共用且需要写在函数内 res = generator() # 生成器函数 : 执行之后会得到一个生成器作为返回值
print(res) # <generator object generator at 0x0000019C239AD4C0> def generator_full():
print(1)
yield 'a' # yield不会结束函数
print(2)
yield 'b'
yield 'c'
g = generator_full()
print(dir(g)) # 它有'__iter__' ret = g.__next__()
print(ret) # 执行步骤:1)执行g.__next__()双下函数;2)调用generator_full函数;3) print(1);4)执行:yield 'a' 返回a,但不退出函数,等待
ret = g.__next__()
print(ret)# 执行步骤:1)执行g.__next__()双下函数;2)调用generator_full函数;3) print(2); 4)yield 'b' 返回b,但不退出函数,等待
# ret = g.__next__()
# print(ret)# 执行步骤:1)执行g.__next__()双下函数;2)调用generator_full函数;3)yield 'c' 返回c,但不退出函数,等待
# ret = g.__next__()
# print(ret)# 执行步骤:1)执行g.__next__()双下函数;2)调用generator_full函数;3)发现没有yield,报错StopIteration for i in g: # 接着上面的继续迭代剩下的元素
print(i) # 用for循环迭代后,无法再迭代了!
# ret = g.__next__()
# print(ret)

4、使用生成器函数来生成200万个“ILOVEU No%d”

def s_generator():
for i in range(200):
yield 'ILOVEU No%d'%i s_g = s_generator()
# for i in s_g:
# print(i)

继续深入

 #需求:我要取出前50个ILOVEU
for i in range(50):
print(s_g.__next__()) i = 0
# 发现是按序号接着取元素,从ILOVEU No50开始取
while i < 50:
i += 1
print('----',s_g.__next__())
# 生成器与迭代器一样,会记录当前取到元素的位置,以及下一个元素的位置,随时都可以得到下一个元素! # 对比for循环列表(list,不是迭代器,但是可以迭代)
li = [2, 4, 6, 8, 10]
for i in li:
print(i)
if i == 6:
break for j in li:
print(j)
# 我们发现,没有从停止的位置的下一个位置取元素,而是重新取出所有元素!
# 原因不是list不是迭代器,for循环时,已经将其转换为迭代器,
# 而是,两次for的时候的迭代器不是同一个! #我们再来看生成器s_generator的例子
g1 = s_generator()
g2 = s_generator()
print(g1.__next__())
print(g2.__next__())
# 结果都是ILOVEU No0,说明同一个生成器(同时也是迭代器),__next__时才会记住元素位置

5、监听文件输入的内容,实时打印到命令行中

#普通方法:
def trip(file_path):
f = open(file_path, encoding='utf-8')
while 1:
line = f.readline() # 每次读一行
if line.strip():
print(line.strip()) # 缺点:不能返回line,如果return,循环就终止了 #trip('../day12_func/user_info') def monitor(file_path):
f = open(file_path, mode='r', encoding='utf-8')
while 1:
line = f.readline()
if line.strip():
yield line.strip() g = monitor('../day12_func/user_info')
for i in g:
if 'python' in i:
print('*****', i) ##修改文件后,按ctrl+s才能有效果!打印结果!

Python进阶-V 迭代器(Iterator)、生成器(Generator)函数的更多相关文章

  1. python 进阶篇 迭代器和生成器深入理解

    列表/元组/字典/集合都是容器.对于容器,可以很直观地想象成多个元素在一起的单元:而不同容器的区别,正是在于内部数据结构的实现方法. 所有的容器都是可迭代的(iterable).另外字符串也可以被迭代 ...

  2. Python进阶之迭代器和生成器

    可迭代对象 Python中任意的对象,只要它定义了可以返回一个迭代器的__iter__方法,或者定义了可以支持下标索引的__getitem__方法,那么它就是一个可迭代对象.简单来说,可迭代对象就是能 ...

  3. Python 闭包、迭代器、生成器、装饰器

    Python 闭包.迭代器.生成器.装饰器 一.闭包 闭包:闭包就是内层函数对外层函数局部变量的引用. def func(): a = "哈哈" def func2(): prin ...

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

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

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

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

  6. Python语言的循环语句、迭代器与生成器、函数学习

    while循环语句 无限循环 我们可以通过设置条件表达式永远不为false来实现无限循环,实例如下: for语句 Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串 Python ...

  7. 【python基础】迭代器和生成器函数

    1.迭代器协议: 1.迭代器协议是指:对象必须提供一个 __next__() 方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代(只能往后走不能往前退) ...

  8. Python学习--07迭代器、生成器

    迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). Python里使用for...in来迭代. 常用可迭代对象有 ...

  9. Python学习笔记 - 迭代器Iterator

    我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的genera ...

随机推荐

  1. [随笔]ICPC2.0

    停更半年了.瞎扯下过去,现在与未来. 一.过去 1.插叙 讲道理我应该早就写这段在博客上了,不知怎么一直忘了. 在6月拿到ICPC南昌邀请赛的Ag还是比较满意,满意的最大原因是我弱校从没拿过Ag(? ...

  2. ASP.NET开发实战——(十二)ASP.NET MVC 与数据库之Entity Framework Migrations

    在开发数据库应用程序的时候,经常会遇到某些表需要添加字段或者修改类型.新增表等需求,而对于EF Code First来说关注的只有实体类,当需求变更时只需要添加新的实体类或者在实体类中添加.删除.修改 ...

  3. 【BZOJ3876】[AHOI2014&JSOI2014] 支线剧情(无源汇有上下界网络流)

    点此看题面 大致题意: 有一张\(DAG\),经过每条边有一定时间,从\(1\)号点出发,随时可以返回\(1\)号点,求经过所有边的最短时间. 无源汇有上下界网络流 这是无源汇有上下界网络流的板子题. ...

  4. matlab练习程序(DBSCAN)

    DBSCAN全称Density-Based Spatial Clustering of Applications with Noise,是一种密度聚类算法. 和Kmeans相比,不需要事先知道数据的类 ...

  5. 重构与模式 (Joshua Kerievsky 著)

    第1章 本书的写作缘由 第2章 重构 第3章 模式 第4章 代码坏味 第5章 模式导向的重构目录 第6章 创建 第7章 简化 第8章 泛化 第9章 保护 第10章 聚集操作 第11章 实用重构 参考文 ...

  6. node启动服务后,窗口不能关闭。pm2了解一下

    在做项目时,遇到一个问题. 项目中要和一个3D模型做交互,而做模型的人,给了一个 js 文件.需要在node环境下,使用vscode调试功能启动的. 而我们使用或者调试的时候,喜欢使用命令咋办? 使用 ...

  7. concurrent (八) Future

    作用: 接受多线程的执行结果 全路径: java.util.concurrent 声明: public interface Future<V> 类图结构: 方法 boolean cance ...

  8. windows上安装python2和python3虚拟环境

    一.windows上安装 1.安装python 分别安装了Python2和Python3 python3.7默认安装目录 C:\Users\Administrator\AppData\Local\Pr ...

  9. python 学习常见问题笔记

    1.for...if...构建List segs = [v for v in segs if not str(v).isdigit()]#去数字 https://www.cnblogs.com/eni ...

  10. js通过值获取数组对象对应下标

    var nn = [ { a: 'ss' },{ a: 'aa' },{ a : '11'},{ a: '33' },{ a: '88' } ] 我要怎么获取 a = 33的下标 var index ...