迭代器生成器生成式

迭代器

什么是迭代器

器 => 工具

迭代: 是一个重复的过程,但每次重复都是基于上一次的结果而来的

**迭代器:**就是一种不依赖于索引的取值工具

特性:

1.是一种通用的迭代取值方案

2.惰性计算,节省内存

为何要有迭代器

# 对于序列类型 str,list,tuple可以依赖索引来迭代取值
# 对于dict,set,文件 python必须为我们提供一种不依赖于索引的迭代取值的方式=》迭代器

可迭代对象:(内置有obj.__iter__()方法)

name='egon'
lis=[1,2,3]
tup=[1,2,3]
dic={'name':'egon'}
s={'a','b','c'}
f=open('file.txt','r',encoding='utf-8')

name.__iter__() 	#字符串类型为可迭代对象
lis.__iter__()		#列表类型为可迭代对象
tup.__iter__()		#元组类型为可迭代对象
dic.__iter__()		#字典类型为可迭代对象
s.__iter__()		#集合为可迭代对象
f.__iter__()		#文件类型为可迭代对象

迭代器对象:(内置有obj.__iter__()方法也有obj.__next__()方法)

文件对象即有obj.__iter__()方法也有obj.__next__()方法属于迭代器对象

调用obj.__iter__()方法

name='egon'
name_iter=name.__iter__()	#调用obj.__iter__()方法可以使可迭代对象变成迭代器对象
name._iter.__iter__()
name_iter.__next__()

总结

1、可迭代对象不一定是迭代器对象
2、迭代器对象一定是可迭代对象
3、调用obj.__iter__()方法,得到的是迭代器对象(对于迭代器对象,执行obj.__iter__()方法得到的仍然是它本身)

迭代器优缺点:

优点:
	1.是一种通用的迭代取值方案

	2.惰性计算,节省内存

缺点:
	1.取值不如索引、key的取值方式灵活

	2.取值是一次性的,只能往后取,不能预估值得个数

示例:

d={"name":"egon","age":18,"sex":"male"}
d_iter=d.__iter__()    #也可以写成d_iter=iter(d)
#迭代器d_iter没有值了,就会抛出异常StopIteration

while True:
    try:
        data=d_iter.__next__();  #也可以写成data=next(d_iter)
        print(d[data])
    except StopIteration:
        print("取值完毕")
        break

for循环原理

dic = {"name": "egon", 'age': 18, 'gender': "male"}
# 1、dic.__iter__()得到一个迭代器对象
dic_iterator = dic.__iter__()	
while True:
    try:
#2、迭代器对象.__next__()拿到一个返回值,然后将该返回值赋值给res
        res = dic_iterator.__next__()  
        print(res)
# 3、循环往复步骤2,直到抛出StopIteration异常for循环会捕捉异常然后结束循环
    except StopIteration:	
        break

for k in dic:
    print(k)

生成器

什么是生成器(就是自定义的迭代器)

但凡是函数内出现了yield关键字,调用函数将不会执行函数体代码,会得到一个返回值,该返回值就是我们自定义的迭代器,称之为生成器

def func():
    print("hello1")
    yield 111
    print("hello2")
    yield 222
    print("hello3")
    yield 333
# 生成器本质就是迭代器 
g = func()
print(g)  
res=next(g)
print(res)
# 执行结果 111
res=next(g)
print(res)

res=next(g)
print(res)

next(g)

yield功能:

#1、yield为我们提供了一种自定义迭代器的方法
#2、yield与return的区别:
    #1、yield可以返回多次值 
    #2、函数暂停与再继续的状态是由yield帮我们保存的

示例:自定义range功能

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

res=my_range(1,10)
for i in res:
    print(i)

生成式

l = ['alex_dsb', 'lxx_dsb', 'wxx_dsb', "xxq_dsb", 'egon']
#1、列表生成式
# 把所有小写字母全变成大写
# new_l=[name.upper() for name in l]
# print(new_l)

# 把所有的名字去掉后缀_dsb
# new_l=[name.replace('_dsb','') for name in l]
# print(new_l)

# 2、字典生成式
# keys=['name','age','gender']
# dic={key:None for key in keys}
# print(dic)

# items=[('name','egon'),('age',18),('gender','male')]
# res={k:v for k,v in items if k != 'gender'}
# print(res)

# 3、集合生成式
# keys=['name','age','gender']
# set1={key for key in keys}
# print(set1,type(set1))

生成器表达式

创建一个生成器对象有两种方式,一种是调用带yield关键字的函数,另一种就是生成器表达式,与列表生成式的语法格式相同,只需要将[]换成(),即:

(expression for item in iterable if condition)
# 生成器表达式
# g=(i for i in range(10) if i > 3)
# !!!!!!!!!!!强调!!!!!!!!!!!!!!!
# 此刻g内部一个值也没有

# print(g,type(g))

# print(g)
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))

#统计文件中的字符个数
with open('笔记.txt',mode='rt',encoding='utf-8') as f:
    # 方式一:
    # res=0
    # for line in f:
    #     res+=len(line)
    # print(res)

    # 方式二:
    # res=sum([len(line) for line in f])
    # print(res)

    # 方式三 :效率最高
    # res = sum((len(line) for line in f))
    # 上述可以简写为如下形式
    res = sum(len(line) for line in f)
    print(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值