前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第13天-迭代器和生成器

第13天-迭代器和生成器

作者头像
py3study
发布2020-01-19 15:09:22
2280
发布2020-01-19 15:09:22
举报
文章被收录于专栏:python3

迭代器

迭代就是重复的一个过程,但是不是单纯的重复,每一次的重复都是基于上一次的结果产生的。不过只记住迭代他就是重复的执行过程就是了。

代码语言:javascript
复制
#单纯的重复不是迭代,例如:
count = 0
while count < 3:
    print(count)
    count += 1

#每一次的重复都是基于上一次的结果产生的,随着count的改变输出不同的结果
count = 0
list = ["a", "b", "c"]
while count < 3:
    print(list[count])
    count += 1

迭代器就是迭代取数的一个工具,关键是我们为什么要用迭代器呢?我们都知道python中主要的一些数据类型有整型,字符串,元祖,列表,字典,集合,文件等。对于整型而言只要一个数没有什么迭代器的概念,对于字符串,元祖和列表我们可以通过索引去取值,但是对于字典,集合以及文件而言,我们怎么去像列表一样进行取值呢?这就是迭代器引入的原因,主要就是为了不依赖与索引进行迭代取值。在python中两个概念,一个就是可迭代对象(只要有__iter__方法的我们就称之为可迭代对象,字符串,元祖,列表,字典,集合都是可迭代对象),二是迭代器对象(不仅要有__iter__方法而且还要有__next__方法,文件是迭代器对象),从上面的描述我们就可以看出来,迭代器对象都是可迭代的对象,但是可迭代对象却不一定是迭代器对象。

迭代器的使用方法

代码语言:javascript
复制
dic = {'name': 'hu', 'age': 12}
iter_dic = dic.__iter__()  # 可迭代对象要变成迭代器才能够进行使用
res = iter_dic.__next__()  # 变成迭代器之后通过__next__方法进行迭代取值
print(res)     # 对于dic迭代的值是key

当迭代器把迭代对象循环完毕之后会报错

代码语言:javascript
复制
dic = {'name': 'hu', 'age': 12}
count = 0
iter_dic = dic.__iter__()  # 可迭代对象要变成迭代器才能够进行使用
while count < len(dic):
    try:   # 当最后一个迭代完了之后会报错,因此我们需要捕捉异常
        res = iter_dic.__next__()  # 变成迭代器之后通过__next__方法进行迭代取值
        print(res)     # 对于dic迭代的值是key
    except StopIteration:
        break

从上面的代码我们就可以看出来,对于迭代器的使用太过于麻烦,因此python给我们专门的设计了一个循环for循环来解决这样的事情,for循环可以专门的去解决可迭代对象的问题,当然迭代器对象的问题也可以,for循环处理的步骤1. 把可迭代对象转换成迭代器,(迭代器的话也会执行__iter__的方法,效果是一样的)2. 循环的去调用__next__方法进行迭代取值。3. 通过try去捕捉异常,捕捉到异常之后停止循环。

代码语言:javascript
复制
# 和上面的代码显示的效果是一样的
dic = {'name': 'hu', 'age': 12}
for i in dic:
    print(i)

生成器

  生成器本质上就是迭代器,只不过这个生成器是我们自己通过yield关键字自己创建的迭代器而已。迭代器有两个优点 1. 可以不依赖与索引迭代取值   2.节省内存。而我们创建生成器为了解决最大的问题其实就是节省内存。

生成器创建的规则, 通过yield关键字进行创建迭代器。yield和return返回的是一样的,只是yield可以中断函数,当我需要的时候可以重新再进行创建

代码语言:javascript
复制
def foo()
    print(1)
    yield "第一"
    print(2)
    yield "第二"

iter_foo = foo()
print(iter_foo)
next(iter_foo)

三元表达式

代码语言:javascript
复制
def max2(a, b):
    if a > b:
        return a
    else:
        return b

a = 1
b = 2

c = a if a > b else b   # 这一行数据就是上面那一个函数的简洁的表达方式
print(c)
c = max2(a, b)
print(c)

列表生成式

代码语言:javascript
复制
l = []
for i in range(10):
    if i > 5:
        s = "egg%s" % i
        l.append(s)
print(l)

l = ["egg%s" % i for i in range(10) if i > 5]  # 这一句话和前面的几句话都是性质是一样的,只是简写了而已
print(l)

生成字典表达式

代码语言:javascript
复制
d = {}
s = [("hu", 12), ("zhou", 14)]
for k, v in s:
    d[k] = v

print(d)


d = {k : v for k, v in s} # 这个是上面几行代码的缩写
print(d)

生成器表达式

代码语言:javascript
复制
res = (i ** 2 for i in range(5))

print(res)
print(next(res))
print(next(res))
print(next(res))

练习题:

1. 编写一个range的生成器

代码语言:javascript
复制
def my_range(start, end , step=1):
    while start < end:
        yield start
        start += step

for i in my_range(0, 10):
    print(i)

View Code

2. 求一个文件中所包含的字符的个数,以及左右行中最大的个数

代码语言:javascript
复制
with open(r'04_多层装饰器的联系.py', 'rt', encoding='utf-8') as f:
    # count = 0
    # for line in f:
    #     count += 1
    # data = f.read()
    # print(len(data))  649
    # count = 0
    # for line in f:
    #     count += len(line)
    # print(count)
    # print(sum(len(line) for line in f))
    print(max(len(line) for line in f))   # 通过生成器表达式一行写出

View Code

3. 模拟管道,实现功能:tail -f access.log | grep '404'

代码语言:javascript
复制
# 2、模拟管道,实现功能:tail -f access.log | grep '404'

import time

def tail(file_path):
    with open(file_path, 'rb') as f:
        f.seek(0, 2)
        while True:
            # 查看是否有新的一行加入
            line = f.readline()
            if line:
                yield line
            else:
                time.sleep(0.2)

def grep(pattern, iter_tail):
    for line in iter_tail:
        line = line.decode('utf-8')
        if pattern in line:
            yield line

for line in grep('404', tail('access.log')):
    print(line)

View Code

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/03/14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档