迭代器|三元表达式|生成器

import numpy as np
'''
迭代:每次获得的结果都基于上次结果来的(更新换代)
迭代器协议:对象必须提供一个【next】方法 ,执行该方法,要么返回迭代器的下一项,要么引起异常
迭代对象(节省内存):实现迭代器协议的对象(内部:__iter__()方法)


for循环的本质:循环所有对象,全部使用迭代器协议
for循环可以遍历(序列【字符串、列表、元祖】、非序列【字典、集合、文件对象】)
'''
'''
疑问解答:(字符串、列表、元祖、字典、集合、文件对象)都不是可迭代对象,
只是for循环调用了他们内部的__iter__方法,把他们变成可迭代对象
'''
x = 'hello'
print(dir(x))     ##查看对应方法
iter_test = x.__iter__()     ###将字符串转化成迭代器对象
print(iter_test)  ##<str_iterator object at 0x000001FE5A566550>迭代器对象的内存地址
print(iter_test.__next__())
print(iter_test.__next__())
print(iter_test.__next__())
print(iter_test.__next__())
print(iter_test.__next__())
# print(iter_test.__next__())
'''
总结:字符串对象执行for循环(内部解析):
1.先__iter__()转化成可迭代对象
2.再__next__()进行迭代(爷-父-子)
3.自动捕捉异常
'''

###序列类的访问(字符串、列表、元祖)
lis = [0,1,2,3,4]
for i in lis:
    print(i)

##迭代器协议取值(先变成迭代器对象)
iter_lis = lis.__iter__()
print(iter_lis.__next__())

##索引遍历
index = 0
while index<len(lis):
    print(lis[i])
    index+= 1

###非序列类型(字典、集合、文件对象)
#集合
s = {1,2,3}
for i in s:
    print(i)
#解析
iter_s = s.__iter__()
print(iter_s)
print(iter_s.__next__())
print(iter_s.__next__())
print(iter_s.__next__())
##字典
dic = {'a':1,'b':2}
iter_dic = dic.__iter__()
print(iter_dic.__next__())    ###取出的是key

##文件对象(先在工作目录创建一个文件)
f = open('test.txt','r+',encoding='utf-8')
# for i in f:
#     print(i)

iter_f = f.__iter__()
print(iter_f.__next__(),end=' ')
print(iter_f.__next__(),end=' ')
print(iter_f.__next__(),end=' ')
print(iter_f.__next__(),end=' ')

##next()同样是将对象变成可迭代对象,再调用.__next__()
dic1 = {'a':1,'b':2,'c':3}
iter_dic1 = dic1.__iter__()
print(next(iter_dic1))
print(next(iter_dic1))
print(next(iter_dic1))
迭代-迭代器协议-迭代对象

生成器特性:【可迭代对象】

1.自动实现迭代器协议 
2.生成器函数 : yield语句:一次返回一个结果,状态保持,下一次接着执行(每走一步,停顿,接着走)
3.三元表达式之列表解析
4.生成器表达式:
'''
##三元表达式
name = 'alex'
res1 = '前真' if name == 'alex' else '后假'
res2 = '前真' if name == 'lex' else '后假'
print(res1,res2)
'''
如果判断【真】,res=‘前真’
如果判断【假】,res=‘后假’
'''

##列表解析
#二元
lis=[i for i in range(10)]
print(lis)
#三元
lis1 = ['鸡蛋%s'%i for i in range(10) if i>5]
print(lis1)
三元表达式-列表解析

生成器:1.生成器表达式(列表解析[]换成())2.生成器函数  yield语句【1.停留状态,下次接着;2.返回一个值】

##1.生成器表达式(列表解析的[]换成()),相对于列表解析更省内存
laomuji = ('鸡蛋%s'%i for i in range(10))
print(laomuji) #<generator object <genexpr> at 0x00000218948C2318>
print(laomuji.__next__())
print(laomuji.__next__())
print(laomuji.__next__())
print(next(laomuji))

print(sum(x**2 for x in range(4))) ##生成器表达式直接计算
print(sum([x**2 for x in range(4)]))##生成器表达式生成列表,再进行计算
##2.生成器函数
def GenerateData(batchsize = 100):
    train_x = np.linspace(-1,1,batchsize)                     ###等差数列(一维数组)
    train_y = 2*train_x+np.random.randn(*train_x.shape)*0.3   ###加入噪声的y=zx (一维数组)
    ##np.random.randn(形状)生成0-1间,包括0但不包括1的随机数

    yield train_x,train_y      ##以生成器方式返回  训练数据 x,y
for i in range(5):
    for x,y in GenerateData():
        print(x[:3])
        print(y[:3])
生成器:两种形式


原文地址:https://www.cnblogs.com/liuhuacai/p/11505723.html