python生成器和迭代器及相关概念

本文介绍了Python中的迭代器和生成器的概念及其使用。包括可迭代对象、迭代器的自动访问、委托迭代、切片操作、跳过元素、所有可能的组合、索引-值对迭代、多个序列迭代、迭代器替代while循环、反向迭代。此外,还讨论了生成器的创建和其重要特性,如send方法,以及上下文管理器的使用。
摘要由CSDN通过智能技术生成

前言

在一种语言中有些语法元素属于高级语法元素,有着一些有趣或者难以理解的特性,其中最常见的是迭代器、生成器、装饰器、上下文管理器本文将介绍迭代器、生成器、上下文管理器。


一、迭代器

可迭代对象

内部持有__iter__()方法的对象。

迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。任何实现了__iter__和__next__()方法即迭代器协议的对象都是迭代器。__iter__返回迭代器自身【对应iter()方法】,__next__返回容器中的下一个值【next(generator),只能依次正序生成,生成数据不能再次生成。所有生成器不能超过迭代次数
】。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。字符串,列表或元组对象都可用于创建迭代器。

使用

迭代器的自动访问

通过上面我们可以知道next()可以返回迭代器的下一个值,但有时候我们需要它自动访问。我们可以用for循环。

with open("exhibitionism.txt") as f:
try:
        while True:
            line=next(f)
            print(line,end=' ')
    except StopIteration:
        pass
#----等价于
with open("exhibitionism.txt") as f:
    while True:
        line=next(f,None)
        if line is None:
            break
        print(line,end='')

注:使用next函数可以了解底层迭代器精细控制的情况。
for循环内部三件事:

  1. 调用可迭代对象的iter方法返回一个迭代器对象。
  2. 不断调用迭代器对象的next方法。
  3. 处理stopIteration
委托迭代

让自己的新容器对象【内部包含持有一个可迭代对象】能够完成迭代操作。一般来说我们要定义一个__iter__()方法,将迭代请求委托到对象内部持有的容器上。

class Node:
    def __init__(self,value):
        self._value=value
        self._children=[]
    def __repr__(self):
        return 'Node({!r})'.format(self._value)
    def add_child(self,node):

        self._children.append(node)
        print(self._children)
    def __iter__(self):
        return iter(self._children)
root=Node(0)
child1=Node(1)
child2=Node(2)
root.add_child(child1)
root.add_child(child2)
for ch in root:
    print(ch)
'''
结果:
[Node(1)]
[Node(1), Node(2)]
Node(1)
Node(2)
'''

对迭代器做切片操作

切片我们不陌生,普通的切片操作不能对迭代器产生的数据做切片处理,itertools.islice()函数是完美的选择。

def Cutdown(n):
    while n>0:
        yield n
        n-=1
#Cutdown(6)[1:2]#'generator' object is not subscriptable
import itertools
s=itertools.islice(Cutdown(6),1,3)#<itertools.islice object at 0x0000017D0696B7C0>

注:islice()函数产生的数据和迭代器一样,只能访问一次,访问多次还需要转换成列表。

跳过可迭代对象中的一部分元素

我们已经知道了普通切片操作无法对生成器使用,如果我需要跳过一部分元素,那应该如何操作呢?需求简单如跳过前N个元素可以使用islice(iter,N,None)的方法。需求复杂你可能会考虑过滤函数filter,其实我们还可以使用itertools.dropwhile(Lf,iterable)【函数参数前者为过滤函数,后者为可迭代对象】。

import itertools
def Cutdown(n):
    while n>0:
        yield str<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值