一、迭代器

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. django 使用HttpResponse返回json数据为中文

    之前我用django一般用JsonResponse来返回json数据格式 但是发现返回中文的时候会乱码 from django.http import JsonResponse def test(re ...

  2. FFT/NTT基础题总结

    在学各种数各种反演之前把以前做的$FFT$/$NTT$的题整理一遍 还请数论$dalao$口下留情 T1快速傅立叶之二 题目中要求求出 $c_k=\sum\limits_{i=k}^{n-1}a_i* ...

  3. Java连载7-变量&数据类型

    一.变量 1.注意点: 在同一个“作用域”中,变量名不能重名,但是变量可以重新赋值. 2.什么是作用域? 答:描述的是变量的有效范围,在范围之内是可以被访问的,只要出了作用域就无法访问(也就是在大括号 ...

  4. CodeForces 574D Bear and Blocks

    Limak is a little bear who loves to play. Today he is playing by destroying block towers. He built n ...

  5. Chrome教程之使用Chrome DevTools命令菜单运行命令

    1.模拟移动设备 点击 Toggle Device Toolbar 2.限制网络流量和 CPU 占用率 要限制网络流量和 CPU 占用率,请从 Throttle 列表中选择 Mid-tier mobi ...

  6. LinqToSql

    string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConsoleA ...

  7. Winform中设置ZedGraph鼠标滚轮缩放的灵敏度以及设置滚轮缩放的方式(鼠标焦点为中心还是图形中心点)

    场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  8. The underlying connection was closed: An unexpected error occurred on a send

    操作系统是Windows Server 2003 x64 SP2,使用Framework 4.0,在使用WebClient访问某些特定的HTTPS站点时,会引发异常: Unhandled Except ...

  9. mssql 导出作业,导出表,导出存储过程等

    1.mssql 导出作业 1.选中sql server 代理-作业 2.点击F7 显示对象资源管理器详细信息,3.按住ctrol 选中 右键编写作业脚本到就可以了 2.mssql 导出表和存储过程等 ...

  10. 解决 bash: vue command not found

    背景  : win10 使用  yarn  全局 安装  vue/cli 后   yarn  global add  @vue/cli 提示安装成功 使用vue create   提示  bash: ...