可迭代对象

字符串、列表、元祖、集合、字典都是可迭代的,数字是不可迭代的。(可以用for循环遍历取出内部元素的就是可迭代的)

如何查看一个变量是否为可迭代:

from collections import Iterable

l = [1,2,3,4]
t = (1,2,3,4)
d = {1:2,3:4}
s = {1,2,3,4} print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))
#结果为True就是可迭代,False就是不可迭代

可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义就是内部实现了__iter__方法,即可迭代对象中封装有__iter__方法。

迭代器

迭代器:用变量调__iter__后就可以生成一个迭代器,迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。

l = [1,2,3,4]
l_iter = l.__iter__()#l_iter只是一个接受的变量
item = l_iter.__next__()#利用迭代器取值
print(item)#
item = l_iter.__next__()
print(item)#
item = l_iter.__next__()
print(item)#
item = l_iter.__next__()
print(item)#
item = l_iter.__next__()
print(item)#超出限度,报错

上步在最后出现了报错情况,为了使程序不报错,可以在取完了的最后将其终止掉:

l = [1,2,3,4]
l_iter = l.__iter__()
while True:
try:
item = l_iter.__next__()
print(item)
except StopIteration:
break

生成器

生成器:(本质就是一个迭代器,不过是由程序员写出来的才叫生成器,内置的就叫迭代器)

  1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行,惰性。

  2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

简易生成器:

import time
def func():
a = 1
print('现在定义了a变量')
yield a
b = 2
print('现在又定义了b变量')
yield b g1 = func()
print('g1 : ',g1) #打印g1可以发现g1就是一个生成器
print('-'*20) #我是华丽的分割线
print(next(g1))
time.sleep(1) #sleep一秒看清执行过程
print(next(g1))#每print一次next才会出来一个yield的值,不然就挂在上一个yield上不继续执行

生成器有什么好处呢?就是不会一下子在内存中生成太多数据,只有在你要的时候才会给你你要的数据

生成器应用的几个小栗子:

有关衣服订单:

def produce():
"""生产衣服"""
for i in range(2000000):
yield "生产了第%s件衣服"%i product_g = produce()
print(product_g.__next__()) #要一件衣服
print(product_g.__next__()) #再要一件衣服
print(product_g.__next__()) #再要一件衣服
num = 0
for i in product_g: #要一批衣服,比如5件
print(i)
num +=1
if num == 5:
break #到这里我们找工厂拿了8件衣服,我一共让我的生产函数(也就是produce生成器函数)生产2000000件衣服。
#剩下的还有很多衣服,我们可以一直拿,也可以放着等想拿的时候再拿

生成器监听文件输入的栗子:

import time

def tail(filename):
f = open(filename)
f.seek(0, 2) #从文件末尾算起
while True:
line = f.readline() # 读取文件中新的文本行
if not line:
time.sleep(0.1)
continue
yield line tail_g = tail('tmp')
for line in tail_g:
print(line)

计算移动平均值(类似于年化收益):

def averager():
total = 0
day = 0
average = 0
while True:
term = yield average
total += term
day += 1
average = total/day g_avg = averager()
next(g_avg)
print(g_avg.send(10))
print(g_avg.send(12))
print(g_avg.send(13))

yield from可以在实行for循环的效果的同时将代码变少:

def gen1():
for c in 'AB':
yield c
for i in range(3):
yield i print(list(gen1()))#['A','B',1,2,3] #简化版本
def gen2():
yield from 'AB'
yield from range(3) print(list(gen2()))#['A','B',1,2,3]

列表推导式和生成器表达式:(这里用一个小故事讲解知识点)

#为了彰显高富帅本质,一口气买了十个茶叶蛋,将他们依次排开并编号,拍照发到朋友圈

egg_list=['茶叶蛋%s' %i for i in range(10)] #列表解析

#可是这十个茶叶蛋一口气吃不完啊,要吃也就是一个一个吃,那么就吃一个拍一个照吧

eat=('茶叶蛋%s' %i for i in range(10))#生成器表达式
print(eat)
print(next(eat)) #next本质就是调用__next__
print(eat.__next__())
print(next(eat))

高富帅与茶叶蛋

总结:

1.把列表解析的[]换成()得到的就是生成器表达式

2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存

3.Python使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。

附:与生成器相关的面试题:

def demo():
for i in range(4):
yield i g=demo() g1=(i for i in g)
g2=(i for i in g1) print(list(g1))#[0,1,2,3]
print(list(g2))#[]

面试题1

def add(n,i):
return n+i def test():
for i in range(4):
yield i g=test()
for n in [1,10]:
g=(add(n,i) for i in g) print(list(g))#[20,21,22,23]

面试题2

what's the python之可迭代对象、迭代器与生成器(附面试题)的更多相关文章

  1. 深入理解python中可迭代对象,迭代器,生成器

    英文原文出处:Iterables vs. Iterators vs. Generators 在python学习中,通常会陷入对以下几个相关概念之间的确切差异的困惑中: a container(容器) ...

  2. python编程系列---可迭代对象,迭代器和生成器详解

    一.三者在代码上的特征 1.有__iter__方法的对象就是可迭代类(对象) 2.有__iter__方法,__next()方法的对象就是迭代器3.生成器 == 函数+yield 生成器属于迭代器, 迭 ...

  3. 11.Python初窥门径(函数名,可迭代对象,迭代器)

    Python(函数名,可迭代对象,迭代器) 一.默认参数的坑 # 比较特殊,正常来说临时空间执行结束后应该删除,但在这里不是. def func(a,l=[]): l.append(a) return ...

  4. Python中的可迭代对象/迭代器/For循环工作机制/生成器

    本文分成6个部分: 1.iterable iterator区别 2.iterable的工作机制 3.iterator的工作机制 4.for循环的工作机制 5.generator的原理 6.总结 1.i ...

  5. Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器

    Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器 一丶关键字:global,nonlocal global 声明全局变量: ​ 1. 可以在局部作用域声明一 ...

  6. python 可迭代对象 迭代器 生成器总结

    可迭代对象 只要有魔法方法__iter__的就是可迭代对象  list和tuple和dict都是可迭代对象 迭代器 只要有魔法方法__iter__和__next__的就是可迭代对象 生成器 只要含有y ...

  7. 可迭代对象&迭代器&生成器

    在python中,可迭代对象&迭代器&生成器的关系如下图: 即:生成器是一种特殊的迭代器,迭代器是一种特殊的可迭代对象. 可迭代对象 如上图,这里x是一个列表(可迭代对象),其实正如第 ...

  8. python14 1.带参装饰器 | wrapper 了了解 # 2.迭代器 ***** # 可迭代对象 # 迭代器对象 # for迭代器 # 枚举对象

    ## 复习 '''函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.验证执行 开放封闭原则: 功能可以拓展,但源代码与调用方式都不可以改变 ...

  9. python当中的 可迭代对象 迭代器

    学习python有一段时间了,在学习过程中遇到很多难理解的东西,做一下总结,希望能对其他朋友有一些帮助. 完全是个人理解,难免有错,欢迎其他大神朋友们批评指正. 1 迭代 什么是迭代呢??我们可以这样 ...

随机推荐

  1. [hive] hiveql 基础操作

    1. 显示当前的数据库信息 直接修改hive.site.xml ,永久显示 2. 建表,模糊显示表信息 drop  table   表名称: --删除表 show tables ;--显示所有表 sh ...

  2. 【代码审计】XIAOCMS_后台database.php页面存在任意文件删除漏洞

      0x00 环境准备 XIAOCMS官网: http://www.xiaocms.com/ 网站源码版本:XiaoCms (发布时间:2014-12-29) 程序源码下载:http://www.xi ...

  3. distri.lua线程间通信的设计

    首先简单介绍下distri.lua中的线程设计方案. distri.lua提供一个API函数fork用于创建新的C线程,这个C线程运行独立的lua虚拟机,为了在各线程之间通信 每个线程都会创建一个ch ...

  4. django通用视图(类方法)

    这周是我入职的第一周,入职第一天看到嘉兴大佬的项目代码.视图中有类方法,我感到很困惑. 联想到之前北京融360的电话面试,问我有无写过类方法……看来有必要了解下视图的类方法,上网搜了很多,原来这就是所 ...

  5. 实验一:基于STM32F1的流水灯实验(库函数)

    参考原子哥学习程序 条件:实验板STM32103ZET6:固件库STM32F10x_StdPeriph_Lib_V3.5.0:环境MDK5: 目的:了解STM32 的 IO 口如何作为输出使用 :以两 ...

  6. 录制用户的音频,视屏 navigator.mediaDevices.getUserMedia

    google 文档 HACKS 文档 相关代码 获取本地的音频 <input type="file" accept="audio/*" capture=& ...

  7. 编译openssl失败(SLES11.3), undefined reference to `OPENSSL_cpuid_setup'

    https://stackoverflow.com/questions/11381514/undefined-reference-when-compiling-openssl I ran into t ...

  8. 洛谷P1141 01迷宫【bfs】

    题目链接:https://www.luogu.org/problemnew/show/P1141 题意: 有一个填了0和1的n*n的格子,只能0走到1,1走到0 有m组询问(数据量是1e5),问某一个 ...

  9. centos 7 部署 MQTT

    官方教程  :头痛的是nginx 和 mqtt布局有所冲突,后台不能使用需要调整,当然是用 nginx自家的布局没问题,但是要收费 官方地址 1.由于emqttd是用Erlang语言编写的,所以,在L ...

  10. Codeforces 44E - Anfisa the Monkey - [水题]

    题目链接:http://codeforces.com/problemset/problem/44/E 题意: 给一个字符串,让你分割成 $k$ 行,每行的字母数在 $[a,b]$ 之间. 题解: 这是 ...