python之迭代器、生成器、三元表达式

'''
迭代器iterator和生成器
#递归:自己 调自己
#迭代:对象必须提供一个next方法,执行该方法要么
返回迭代中的下一项,要么就引起一个 stopiterarion异常,
以终止迭代(只能往后走,不能往前走)
可迭代器对象:实现了迭代器协议的对象,__iter__()方法
协议是一种 约定,可迭代对象实现了迭代器协议,Python的内部
工具(如for循环 )
'''
# for循环的本质:循环所有对象,全都是使用迭代器协议
# 迭代器就是可迭代对象

L = ['dad', 'son', 'chongson']
iter_l = L.__iter__()
# print(iter_l.__next__())
# print(iter_l.__next__())
# print(iter_l.__next__())
print(next(iter_l))  # 两种调用方法,上面注释和此处next

一 迭代的概念

复制代码
#迭代器即迭代的工具,那什么是迭代呢?
#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而不是迭代 print('===>') l=[1,2,3] count=0 while count < len(l): #迭代 print(l[count]) count+=1
复制代码

二 为何要有迭代器?什么是可迭代对象?什么是迭代器对象?

#1、为何要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器

#2、什么是可迭代对象?
可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下
'hello'.__iter__
(1,2,3).__iter__
[1,2,3].__iter__
{'a':1}.__iter__
{'a','b'}.__iter__
open('a.txt').__iter__

#3、什么是迭代器对象?
可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象

文件类型是迭代器对象
open('a.txt').__iter__()
open('a.txt').__next__()


#4、注意:
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

迭代器的优缺点

#优点:
  - 提供一种统一的、不依赖于索引的迭代方式
  - 惰性计算,节省内存
#缺点:
  - 无法获取长度(只有在next完毕才知道到底有几个值)
  - 一次性的,只能往后走,不能往前退
'''
生成器generator:一种数据类型,自动实现了迭代器协议,生成器就是可迭代对象
生成器函数,使用yield语句 而不是return语句返回结果,yield语句一次返回一个结果

'''
生成器

def test():
    yield 1


g = test()
print(g.__next__())

生成器就是迭代器


g.__iter__
g.__next__
#2、所以生成器就是迭代器,因此可以这么取值
res=next(g)
print(res)
# 生成器表达式
'''
1、把列表解析的[]换成()得到的就是生成器表达式
2、列表解析与生成器表达式都是一种遍利的编程方式,生成器表达式更节省内存
3、Python使用迭代器协议,让for循环变得更加通用
sum()、map()、reduce()、filter()等
'''

# 三元 表达式
name = 'tom'
res = 'sb' if name == 'tom' else '度挨个'
print(res)

# 给一筐鸡蛋,列表解析
egg_l=[]
for i in range(10):
    egg_l.append('鸡蛋%s'%i)
print(egg_l)

# 转成生成器
#最多只有三元表达式,没有四元表达式
l = ['鸡蛋%s' % i for i in range(10)]
l1 = ['鸡蛋%s' % i for i in range(10) if i >5  ]
print(l1)
print(l)

#生成器表达式
chicken  = ('鸡蛋%s'%i for i in range(10))
print(chicken)
print(chicken.__next__())


print(sum(list(range(10000))))
print(sum(list(range(101))))

练习 :

1、将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写

2、将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后保存剩下的名字长度

3、求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数)

4、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?(需要使用sum函数)

#1、
names=['egon','alex_sb','wupeiqi','yuanhao']
names=[name.upper() for name in names]
print(names)

#2
name1=[len(name) for name in names if not name.endswith('sb')]
print(name1)

#3
with open('22','r',encoding='utf-8') as f:
    print(max(len(line)) for line in f)

#4
with open('22','r',encoding='utf-8') as f:
    print(sum(len(line)) for line in f)
View Code

5、思考题

with open('a.txt') as f:
    g=(len(line) for line in f)
print(sum(g)) #为何报错?
修改后

6、文件shopping.txt内容如下

mac,20000,3
lenovo,3000,10
tesla,1000000,10
chicken,200,1

求总共花了多少钱?

打印出所有商品的信息,格式为[{'name':'xxx','price':333,'count':3},...]

求单价大于10000的商品信息,格式同上

#有问题
with open('a.txt',encoding='utf-8') as f:
    info=[line.split() for line in f]
    cost=sum(float(unit_price)*int(count) for _,unit_price,count in info)
    print(cost)


with open('a.txt',encoding='utf-8') as f:
    info=[{
        'name': line.split()[0],
        'price': float(line.split()[1]),
        'count': int(line.split()[2]),
    } for line in f]
    print(info)


with open('a.txt',encoding='utf-8') as f:
    info=[{
        'name': line.split()[0],
        'price': float(line.split()[1]),
        'count': int(line.split()[2]),
    } for line in f if float(line.split()[1]) > 10000]
    print(info)
View Code

 

https://www.cnblogs.com/linhaifeng/articles/7580428.html 更详细阅读此博主文章

posted @ 2022-08-08 16:09  ilspring  阅读(45)  评论(0)    收藏  举报