四、迭代器、生成器、三元表达式、列表生成式

一、迭代器

  1.1 什么是迭代器

#迭代的工具


#什么是迭代?
#迭代是一个重复的过程,每一次重复都是基于上一次结果而进行的


#错误案例:
#单纯的重复不是迭代
while True:
    print ('===>')


#正确案例:
count=0
while count >10:    #重复的过程
    count +=1    #每一次重复都是基于上一次的结果而进行的
    print (count)

  1.2 为什么要用迭代器

#找到一种可以不依赖索引的迭代取值方式

  1.3 怎么用迭代器

名词介绍:
#1.可迭代对象iterable:
#在python中,但凡内置有__iter__方法对象,都是可迭代的对象

#2.迭代器对象iterator:
#执行可迭代对象下__iter__方法得到的返回值就是一个迭代器对象

#3.迭代器对象内置:
#__next__方法
#__iter__方法,执行该方法得到仍然是迭代器本身

#由第3点可知迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象


使用迭代器原理:
#1.使用可迭代对象(如,列表,字典等等)的__inter__方法,返回值为迭代器对象iterator
#2.使用迭代器对象里的__next__方法(或next(迭代器对象))取到迭代器里的一个值
#3.重复步骤2,直到遇到StopIteration报错提示,显示值已取完


#迭代器使用例子:
names=['唐三', '小舞', '唐昊', '胖子', '戴沐白']
iterator_obj=names.__iter__()   #可迭代对象.__iter__()返回值为迭代器对象
iterator_obj.__next__()
iterator_obj.__next__()
iterator_obj.__next__()
iterator_obj.__next__()
iterator_obj.__next__()
iterator_obj.__next__()


#for循环的底层运行机制:for循环可以称之为迭代器循环
#1.先调用in后那个对象的__iter__方法,得到该对象的迭代器对象
#2.执行迭代器对象的__next__方法,将得到的返回值赋值给In前面的变量名,然后执行一次循环体代码
#3.循环往复,直到取干净迭代器内所有的值,自动捕捉异常结束循环

#例子:
dic = {'name':'唐三','level':29,'sex':''}
for k in dic:   #dic.__iter__()==>obj.__next()==>k
    print (k)

  1.4 总结迭代器

#优点:
#1.提供一种不依赖与索引的迭代取值方式===》应用于for循环
#2.节省内存

#缺点:
#1.只能往后取,不能往前取,是一次性的,值取干净后无法再次取值,除非重新得到新的迭代器对象,不如按照索引取值的方式灵活
#2.值没取完,永远无法预测迭代器的长度

  1.5  Python2.x与Python3.x中的range()

#Python2.x中的range()返回的结果是列表
#Python3.x中range()返回的结果是可迭代对象

二、生成器

  2.1 什么是生成器

#在函数内但凡有yield关键字,在调用函数就不会执行函数体代码,得到的返回值就是一个生成器对象
#强调:生成器本质就是迭代器


#next(g)过程:
#会触发生成器g所对应的函数的执行,直到遇到yield才停下来,然后把yield后的返回值当做本次next操作的结果

  2.2 为何要用生成器

#为了掌握一种自定义迭代器的方式

  2.3 总结yield:

#1.yield提供一种自定义迭代器的方式
#2.与return对比,都能返回值,都能返回多个值,都没有类型限制
#3.不同的是:而return只能返回一次值,而yield可以返回多次值(yield可以帮我们保存函数的执行状态)

#例子:
def func():
    print ('first')
    yield 1     #暂停
    print ('second')
    yield 2     #第二次暂停位置
    print ('third')

g=func()    #返回值为生成器对象
print (next(g))
print (next(g))
print (next(g)) #报错,因为第三次只有函数体没有yield,for循环可以规避这个问题for i in fun():print (i)

  2.4 例子: 实现range()功能

def myrange(start,end,step=1):
    while start < end:
        yield start
        start += step

g=myrange(1,10,2)
for i in g:
    print (i)
View Code

  2.5 yield 的表达式形式应用

def people(name):
    print ('[%s]去过的城市'%name)
    travel_city=[]
    while True:
        city=yield travel_city    #yield表达式应用
        print ('[%s]去了%s'%(name,city))
        travel_city.append(city)

g=people('唐三')
next(g)     #第一次为空列表,也可使用g.send(None)
g.send('广州')
g.send('青海')
print ('都去过的城市列表:',g.send('西双版纳'))

·  2.6 生成器表达式

g= (i for i in range(10000000000000000000000000000000000))  #返回生成器
print (type(g),g)
print (next(g))


#需求:计算文件中最长的行长度,打印长度与内容
with open('file1.txt','r',encoding='utf-8') as f:
    g=((len(line),line) for line in f)
    print (max(g))

三、三元表达式

#普通做法
def max2(x,y):
    if x>y:
        return x
    else:
        return y

res=max2(1,3)

#三元表达式
x=10
y=30

res=x if x>x else y    #三元表达式
print (res)

  四、列表生成式

  4.1 定义

#普通做法
l=[]
for i in range(10):
    l.append('egg%s'%i)
print (l)

#列表生成式
l=['egg%s'%i for i in range(10)]
print (l)

  4.2 举例

#需求:将名字前面加上序号
names=['路飞','索隆','娜美','乔巴','香吉士']
names=[str(index+1)+name for index,name in enumerate(names)]
print (names)

#需求:将带有.jpg的名字过滤掉
names=['路飞.jpg','索隆.pdf','娜美.jpg','乔巴.pdf','香吉士.jpg']
names=[name for name in names if not name.endswith('.jpg')]
print (names)

五、字典生成式

#字典生成式1
d={i:i for i in range(10) if i>0}
print (d)

userinfo
=[('路飞','15亿'),('索隆','3亿2千万'),('乔巴','100')] user_dic={i[0]:i[1] for i in userinfo} print (user_dic)

猜你喜欢

转载自www.cnblogs.com/lisenlin/p/9006736.html