Python迭代器和生成器

1.迭代器

迭代:可以将某个数据集内的数据“一个挨着一个的取出来”

for i in range(1, 10, 2):  # in 后面的对象必须是一个可迭代的
print(i) # 从可迭代对象中将元素一个一个取出
"""
判断是否可迭代
"""
from collections import Iterable str1 = 'adc'
l = [1, 2, 3, 4]
t = (1, 2, 3, 4)
d = {1: 2, 3: 4}
s = {1, 2, 3, 4}
print(isinstance(str1, Iterable))
print(isinstance(l, Iterable))
print(isinstance(t, Iterable))
print(isinstance(d, Iterable))
print(isinstance(s, Iterable)) # True int1 = 1234
print(isinstance(int1, Iterable)) # False

2.可迭代协议

可以被迭代要满足的要求就叫做可迭代协议。内部实现了__iter__方法。

print(dir(str))  # 可迭代,内部要有一个__iter__()方法
print(str1.__iter__())
#['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
#<str_iterator object at 0x0000000000A6DB38>
str_iterator iterator 就是迭代器
str1 = 'abc'
dir(str1) # 列出所有字符串实现的方法
set1 = set(dir(str1))
set2 = set(dir(str1.__iter__()))
print(set2 - set1)
# {'__length_hint__', '__next__', '__setstate__'}

迭代器多了三个方法

"""迭代器中的方法作用"""
str1 = 'abc'
# 获取迭代器
iter_1 = str1.__iter__()
# 获取迭代器中元素的长度
print(iter_1.__length_hint__()) # 3
# 根据索引值指定从哪里开始迭代
print(iter_1.__setstate__(1)) # None
# 一个一个的取值
print(iter_1.__next__()) # b for 循环内部调用 实现一个一个取值

自己实现迭代取数:

str1 = 'abc'
# 获取迭代器
iter1 = str1.__iter__() # 循环取出
while 1 :
a = iter1.__next__()
print(a)
# a
# b
# c
#
# Traceback (most recent call last):
# File "E:/Python/d01/函数.py", line 8, in <module>
# a = iter1.__next__()
# StopIteration

异常机制处理异常:

str1 = 'abc'
# 获取迭代器
iter1 = str1.__iter__() # 循环取出
while 1:
try:
a = iter1.__next__()
print(a)
except StopIteration:
break
# a
# b
# c

3.生成器

实现迭代器功能的东西就是生成器

Python中提供的生成器:

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

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

生成器Generator:

  本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)

  特点:惰性运算,开发者自定义

生成器函数

1.生成器函数:一个包含yield关键字的函数就是一个生成器函数。
2.yield与reduce区别:
yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,
而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。
def genrator_f1():
a = 1
print('a变量')
yield a
b = 2
print('b变量')
yield b g1 = genrator_f1() # g1获取的是生成器
print(g1.__next__())
print(g1.__next__())
print(g1.__next__()) # a变量
#
# b变量
#
# Traceback (most recent call last):
# File "E:/Python/d01/test.py", line 14, in <module>
# print(g1.__next__())
# StopIteration

生成器的优点:不会在内存中瞬间生成很多数据

def produce():
for i in range(10):
yield "生产序列号:%d" % i # 获取生成器
pro_g = produce()
print(pro_g.__next__()) # 一个一个获取
print(pro_g.__next__())
print(pro_g.__next__()) num = 0 # 批量获取
for i in pro_g:
print(i)
num += 1
if num == 5:
break
# 生产序列号:0
# 生产序列号:1
# 生产序列号:2
# 生产序列号:3
# 生产序列号:4
# 生产序列号:5
# 生产序列号:6
# 生产序列号:7

实现日志实时监控: Linux tail -f

import time

def tail(filename):
with open(filename,mode='r',encoding='utf-8') as f:
f.seek(0, 2) # 从文件末尾算起
while True:
line = f.readline() # 读取文件中新的文本行
if not line:
time.sleep(1)
continue
yield line tail_g = tail('C:\\Users\\18047463\\Desktop\\test.txt')
for line in tail_g:
print(line.strip())

实时计算平均数:

def averager():
total = 0.0
count = 0
average = None
while 1:
term = yield average
total += term
count += 1
average = total / count g_avg = averager()
g_avg.__next__() # 初始化
while 1:
num = input(">>>")
if num == 'q':
break
print(g_avg.send(int(num)))

初始化使用装饰器:

from functools import wraps

def init(func):
@wraps(func)
def inner(*args, **kwargs):
g = func(*args, **kwargs)
g.__next__()
return g return inner @init
def averager():
total = 0.0
count = 0
average = None
while 1:
term = yield average
total += term
count += 1
average = total / count g_avg = averager()
while 1:
num = input(">>>")
if num == 'q':
break
print(g_avg.send(int(num)))
def gen1():
for c in 'AB':
yield c
for i in range(3):
yield i print(list(gen1())) def gen2():
yield from 'AB'
yield from range(3) print(list(gen2()))

列表推导式和生成器表达式

egg_list=['鸡蛋%s' %i for i in range(10)]  #列表解析
print(egg_list)
# ['鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9']
laomuji=('鸡蛋%s' %i for i in range(10)) #生成器表达式 相比列表解析,更加节省内存
print(laomuji) # <generator object <genexpr> at 0x00000000013F8780>
print(next(laomuji)) #next本质就是调用__next__
print(laomuji.__next__())
print(next(laomuji))

python基础篇_005_迭代器和生成器的更多相关文章

  1. python 基础篇 13 迭代器与生成器

    13. 前⽅⾼能-迭代器和⽣成器本节主要内容:1. 迭代器2. ⽣成器 ⼀. 迭代器我们之前⼀直在⽤可迭代对象进⾏迭代操作. 那么到底什么是可迭代对象. 本⼩节主要讨论可迭代对象. ⾸先我们先回顾⼀下 ...

  2. 【笔记】Python基础四:迭代器和生成器

    一,迭代器协议和for循环工作机制 (一),迭代器协议 1,迭代器协议:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个stopiteration异常,以终止迭代(只能往 ...

  3. python基础知识7——迭代器,生成器,装饰器

    迭代器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器 ...

  4. Python基础入门(迭代器和生成器)

    1 Python迭代器 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退. 迭代器有两个基本的方法:iter() 和 ...

  5. python基础9 (迭代器、生成器)

    1.可迭代对象 迭代:将某个数据集内的数据“一个挨着一个的取出来” 可迭代协议:可以被迭代要满足的要求,即内部含有__iter__()方法 可迭代的类型:字符串.列表.元组.字典.集合特点:惰性运算 ...

  6. python基础——9(迭代器、生成器)

    一.迭代器 1.概念 器:包含了多个值的容器 迭代:循环反馈(一次从容器中取出一个值) 迭代器:从装有多个值的容器中一次取出一个值给外界 s = 'abcdef' ls = [1,2,3,4,5] 遍 ...

  7. python基础十一之迭代器和生成器

    可迭代 内置方法中含有__iter__的数据类型都是可迭代的,只要是可迭代的就可以使用for循环,反之亦然. print(dir('')) # dir()函数可以获取当前数据类型的所有内置方法 返回值 ...

  8. Python基础——函数的迭代器和生成器

    等待更新…………………… 后面再写

  9. 完全理解 Python 迭代对象、迭代器、生成器

    完全理解 Python 迭代对象.迭代器.生成器 2017/05/29 · 基础知识 · 9 评论 · 可迭代对象, 生成器, 迭代器 分享到: 原文出处: liuzhijun    本文源自RQ作者 ...

随机推荐

  1. webpack学习记录 - 学习webpack-dev-server(三)

    怎么用最简单的方式搭建一个服务器? 首先安装插件 npm i --save-dev webpack-dev-server 然后修改 packet.json 文件 "scripts" ...

  2. hdu5238 calculator (线段树+crt)

    (并不能)发现29393不是质数,而是等于7*13*17*19 于是可以用四个线段树分别维护模意义下,对x进行一个区间的操作后的值 最后再把这四个的答案用crt拼起来 也可以不crt,而是预处理0~2 ...

  3. Django模板

    Django模板系统 官方文档 常用语法 只需要记住两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 { 变量名 }} 变量名由字母数字和下划线组成. 点 ...

  4. markdown笔记实现页内目录跳转

    方法一 使用Markdown的语法来增加跳转链接:[名称](#id). 1. 只要()内 #号 后面的内容和锚点处标签内的id对应即可,可以任意使用标签支持html语法 2. id不可以有括号和空格, ...

  5. [九省联考2018]秘密袭击coat

    [九省联考2018]秘密袭击coat 研究半天题解啊... 全网几乎唯一的官方做法的题解:链接 别的都是暴力.... 要是n=3333暴力就完了. 一.问题转化 每个联通块第k大的数,直观统计的话,会 ...

  6. Mycat的读写分离

    1. Mycat实现读写分离的部署: https://www.cnblogs.com/softidea/p/5447566.html springboot动态数据源的原理以及配置: Spring内置了 ...

  7. python 爬虫之beautifulsoup(bs4)环境准备

    环境准备: bs4安装方法:https://blog.csdn.net/Bibabu135766/article/details/81662981 requests安装方法:https://blog. ...

  8. vue动态添加对象属性,视图不渲染

    发现数据确实改变了.但是视图没有渲染.原因是赋值的问题,应该这样动态增加属性 vm.$set(vm.template.titleAttachInfoDetail,newKey,newVal) vm 当 ...

  9. Entity Framework入门教程(11)---EF6中的异步查询和异步保存

    EF6中的异步查询和异步保存 在.NET4.5中介绍了异步操作,异步操作在EF中也很有用,在EF6中我们可以使用DbContext的实例进行异步查询和异步保存. 1.异步查询 下边是一个通过L2E语法 ...

  10. Entity Framework入门教程(16)---Enum

    EF DbFirst模式中的枚举类型使用 这一节介绍EF DbFirst模式中的Enum(枚举类型),CodeFirst模式中的Enum会在以后的EF CoreFirst系列中介绍.EF5中添加了对E ...