迭代器 订阅
迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。 展开全文
迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。
信息
外文名
iterator
别    称
游标卡尺
提出者
张康健
中文名
迭代器
适用领域范围
IT行业
迭代器解释
迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来。迭代器提供一些基本操作符:*、++、==、!=、=。这些操作和C/C++“操作array元素”时的指针接口一致。不同之处在于,迭代器是个所谓的复杂的指针,具有遍历复杂数据结构的能力。其下层运行机制取决于其所遍历的数据结构。因此,每一种容器型都必须提供自己的迭代器。事实上每一种容器都将其迭代器以嵌套的方式定义于内部。因此各种迭代器的接口相同,型号却不同。这直接导出了泛型程序设计的概念:所有操作行为都使用相同接口,虽然它们的型别不同。迭代器使开发人员能够在类或结构中支持foreach迭代,而不必整个实现IEnumerable或者IEnumerator接口。只需提供一个迭代器,即可遍历类中的数据结构。当编译器检测到迭代器时,将自动生成IEnumerable接口或者IEnumerator接口的Current,MoveNext和Dispose方法。1.迭代器是可以返回相同类型值的有序序列的一段代码;2.迭代器可用作方法、运算符或get访问器的代码体;3.迭代器代码使用yieldreturn语句依次返回每个元素,yield break将终止迭代;4.可以在类中实现多个迭代器,每个迭代器都必须像任何类成员一样有惟一的名称,并且可以在foreach语句中被客户端,代码调用如下所示:foreach(int x in SimpleClass.Iterator2){};5.迭代器的返回类型必须为IEnumerable和IEnumerator中的任意一种;6.迭代器是产生值的有序序列的一个语句块,不同于有一个 或多个yield语句存在的常规语句块;7.迭代器不是一种成员,它只是实现函数成员的方式,理解这一点是很重要的,一个通过迭代器实现的成员,可以被其他可能或不可能通过迭代器实现的成员覆盖和重载;8.迭代器块在C#语法中不是独特的元素,它们在几个方面受到限制,并且主要作用在函数成员声明的语义上,它们在语法上只是语句块而已;9.yield关键字用于指定返回的值。到达yieldreturn语句时,会保存当前位置。下次调用迭代器时将从此位置重新开始执行。 迭代器对集合类特别有用,它提供一种简单的方法来迭代不常用的数据结构(如二进制树)。迭代器是一种检查容器内元素并遍历元素的可带泛型数据类型。
收起全文
精华内容
参与话题
问答
  • 迭代器

    千次阅读 2020-06-29 20:29:07
    迭代器 1.说明是迭代器(iter) 迭代器就是容器型数据类型,只能通过类型转换和生成器来获得迭代器对象 迭代器存储数据的特点:同时可以保存多个数据,没有办法直接查看,而是需要先将数据从迭代器中取出来,取出来...

    迭代器

    1.说明是迭代器(iter)

    迭代器就是容器型数据类型,只能通过类型转换和生成器来获得迭代器对象
    迭代器存储数据的特点:同时可以保存多个数据,没有办法直接查看,而是需要先将数据从迭代器中取出来,取出来后不能再放进去
    所有的容器都可以转换成迭代器

    iter1 = iter([1,2,3,4])
    print(iter1)
    
    iter2 = iter('abc')
    print(iter2)
    
    iter3 = iter({'a':1})
    print(iter3)
    2. 获取迭代器中的元素

    无论通过什么样的方式,只要将迭代器中的某个元素拿到了,那么这个元素在迭代器中就不存在了

    list1 = list(iter1)
    print(list1)
    list2 = list(iter1)
    print(list2)
    1) 遍历
    iter5 = iter('hello')
    for i in iter5:
        print(f'x:{i}')
    2) 获取单个元素

    next - 获取迭代器中的一个元素(当前最前面的那个元素)
    迭代器对象.next()- 获取迭代器中的一个元素(当前最前面的元素)

    iter6 = iter('hello')
    print(next(iter6))
    print(next(iter6))
    print(next(iter6))
    print(next(iter6))
    print(next(iter6))
    展开全文
  • 一、迭代器的头文件 所有的容器都定义有自己的iterator类型,因此如果单单使用容器,只需要包含对应容器的头文件即可 不过有些特殊的iterator,被定义在头文件<iterator>中 二、迭代器介绍 类似于容器,...

    一、迭代器的头文件

    • 所有的容器都定义有自己的iterator类型,因此如果单单使用容器,只需要包含对应容器的头文件即可
    • 不过有些特殊的iterator,被定义在头文件<iterator>中

    二、迭代器介绍

    • 类似于容器,迭代器也定义了一组公共操作:
      • 一些操作所有迭代器都支持
      • 另外一些只有特定类型的迭代器才支持
    • 例如,ostream_iterator只支持递增、解引用、赋值。vector、string等容器的迭代器除了这些操作之外,还支持递减、关系、算术运算

    迭代器的继承关系

    三、五大类迭代器

    输入迭代器(input iterator)

    • 输入迭代器可以读取序列中的元素
    • 输入迭代器必须支持:
      • 用于比较两个迭代器的相等和不相等运算符(==、!=)
      • 用于推进迭代器的前置和后置递增运算(++)
      • 用于读取元素的解引用运算符(*);解引用只会出现在赋值运算符的右侧
      • 箭头运算符(->)等价于(*it).member,即,解引用迭代器,并提取对象的成员
    • 特点:
      • 输入迭代器只用于顺序访问
      • 对于一个输入迭代器,*it++保证是有效的,但递增它可能导致所有其他指向流的迭代器失效。其结果就是,不能保证输入迭代器的状态可以保存下来并用来访问元素。因此,输入迭代器只能用于单遍扫描算法
      • 例如,算法find和accumlate要求输入迭代器,而istream_iterator是一种输入迭代器

    输出迭代器(output iterator)

    • 输出迭代器可以看做输入迭代器功能上的补集——只可以写而不可以读取元素
    • 输出迭代器必须支持:
      • 用于推进迭代器的前置和后置递增运算(++)
      • 解引用运算符(*),只出现在赋值运算符的左侧(向一个已经解引用的输出迭代器赋值,僵尸将值写入它所指的元素)
    • 特点:
      • 我们只能向一个输出迭代器赋值一次
      • 类似输入迭代器,输出迭代器只能用于单遍扫描算法。用作目的位置的迭代器通常都是输出迭代器
      • 例如,copy算法的第三个参数就是输出迭代器,ostream_iterator类型也是输出迭代器

    前向迭代器(forward iterator)

    • 可以读写元素
    • 特点:
      • 这些迭代器只能在序列中沿一个方向移动
      • 前进迭代器支持所有输入和输出迭代器的操作,而且可以多次读写同一个元素
      • 因此,我们可以保存前向迭代器的状态,使用前向迭代器的算法可以对序列进行多遍扫描
      • 例如,算法replace要求前向迭代器,forward_list容器上的迭代器是前向迭代器

    双向迭代器(binirectional iterator)

    • 可以正向/反向读写序列中的元素
    • 特点:
      • 除了支持所有前向迭代器的操作之外,双向迭代器还支持前置和后置递减 运算符(--)
      • 例如,算法reverse要求双向迭代器,除了forward_list容器之外,其他标准库都提供符合双向迭代器要求的迭代器

    随机访问迭代器(random-access iterator)

    • 提供在常量时间内访问序列中任意元素的能力,此类迭代器支持双向迭代器的所有功能
    • 另外还支持:
      • 用于比较两个迭代器相对位置的关系运算符(<、<=、>、>=)
      • 迭代器和一个整数值的加减运算(+、+=、-、-=),计算结果是迭代器在序列中前进(或后退)给定整数个元素后的位置
      • 用于两个迭代器上的减法运算符(-),得到两个迭代器的距离
      • 下标运算符(iter[n]),与*(iter[n])等价

    • 例如,算法sort要求随机访问迭代器。array、deque、string、vector的迭代器都是随机访问迭代器,用于访问内置数组元素的指针也是
    展开全文
  • python 迭代器 生成器 解析

    万次阅读 2018-08-21 17:36:22
    迭代器 什么是迭代器 迭代器是访问可迭代对象的工具 迭代器是指iter(obj)函数返回的对象(实例) 迭代器可以用next(it)函数获取可迭代对象的数据 迭代器函数iter和next iter(iterable)从可迭代对象中返回一...
    迭代器
      什么是迭代器
      迭代器是访问可迭代对象的工具
      迭代器是指iter(obj)函数返回的对象(实例)
      迭代器可以用next(it)函数获取可迭代对象的数据
    迭代器函数iternext
    iter(iterable)从可迭代对象中返回一个迭代器
    Iterable,必须能提供一个可迭代对象
    next(Iterator)从迭代器中获取下一个记录,如果无法获取下一条记录则触发stopiterator异常
    说明
    1.迭代器只能往前取值,不会后退
    2.iter函数可以返回一个可迭代对象的迭代器
    实例
    >>> l=[1,2,3,45,6,7,9]
    >>> i=iter(l)
    >>> next(i)
    1
    >>> next(i)
    2
    >>> next(i)
    3
    >>> next(i)
    45
    >>> next(i)
    6
    >>> next(i)
    7
    >>> next(i)
    9
    >>> next(i)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>> 
    
    
    迭代器的用途
      用迭代器可以依次访问可迭代对象的数据
      l=[1,2,34,5]
      for i in l :
      	print(x)
    >>> l=[1,2,34,5]
    >>> it=iter(l)
    >>> while True:
    	try:
    		
    		x=next(it)
    		print(x)
    	except StopIteration:
    		break
    
    	
    1
    2
    34
    5
    s={'唐僧','悟空','八戒','沙僧'}
    it=iter(s)
    while True:
        try:
            print(next(it))
        except StopIteration:
            break
    
    生成器
    什么是生成器
    生成器是能够动态提供数据的对象,生成器对象也是可迭代对象
    生成器有两种
    1生成器函数
    2生成器表达式
    生成器函数的定义
    含有yield语句的函数是生成器,此函数被调用将返回一个生成器对象
    yield  翻译为产生(或生成)
    yield 语句
    语法 yield
    
    说明:
        yield 用于def 函数中目的是将此函数作用生成器函数使用yield
        用来生成数据,供迭代器和next(it)函数使用
    把生成器变成迭代器
    def gen():
        for i in range(20):
            print('qqqq')
            yield i
    
    gen1=gen()
    
    it=iter(gen1)
    
    while True:
        try:
            print(next(it))
        except StopIteration:
            break
    
    
    def gen():
        for i in range(20):
            print('qqqq',i)
            yield gen()
    for i in gen():
        print(i)
        qqqq 0
    <generator object gen at 0x7fc294b04f10>
    qqqq 1
    <generator object gen at 0x7fc294b04f68>
    qqqq 2
    <generator object gen at 0x7fc294b04f10>
    qqqq 3
    <generator object gen at 0x7fc294b04f68>
    qqqq 4
    <generator object gen at 0x7fc294b04f10>
    qqqq 5
    <generator object gen at 0x7fc294b04f68>
    qqqq 6
    <generator object gen at 0x7fc294b04f10>
    qqqq 7
    <generator object gen at 0x7fc294b04f68>
    qqqq 8
    <generator object gen at 0x7fc294b04f10>
    qqqq 9
    <generator object gen at 0x7fc294b04f68>
    qqqq 10
    <generator object gen at 0x7fc294b04f10>
    qqqq 11
    <generator object gen at 0x7fc294b04f68>
    qqqq 12
    <generator object gen at 0x7fc294b04f10>
    qqqq 13
    <generator object gen at 0x7fc294b04f68>
    qqqq 14
    <generator object gen at 0x7fc294b04f10>
    qqqq 15
    <generator object gen at 0x7fc294b04f68>
    qqqq 16
    <generator object gen at 0x7fc294b04f10>
    qqqq 17
    <generator object gen at 0x7fc294b04f68>
    qqqq 18
    <generator object gen at 0x7fc294b04f10>
    qqqq 19
    <generator object gen at 0x7fc294b04f68>
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
    生成器函数的说明
    生成器函数的调用将返回一个生成器对象
    生成器对象是一个可迭代对象
    通常用来动态生成数据
    生成器函数调用return 会触发一个StopIteration异常
    def myrange(start,stop,step=1):
        while start<stop-1:
            start+=step
            yield start
    for x in myrange(0,30,2):
        print(x)
    l=[x**2 for x in myrange(0,30)]
    print(l)
    2
    4
    6
    8
    10
    12
    14
    16
    18
    20
    22
    24
    26
    28
    30
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841]
    def jiecheng(n):
        for i in range(1,n+1):
            x=1
            for j in range(1,i+1) :
                x*=j
            yield x
    l=list(jiecheng(5))
    print(l)
    
    生成器表达式
    语法
    (表达式 for i in 可迭代对象 [if 真值表达式])
    作用:
    用推导式创建一个新生成器
    说明
    if 可以省略
    
    >>> gen=(x**2 for x in range(1,5) )
    >>> it=iter(gen)
    >>> print(next(it))
    1
    >>> print(next(it))
    4
    >>> print(next(it))
    9
    >>> print(next(it))
    16
    >>> print(next(it))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>> 
    # def pingfangjianyi(n):
    #     i=1
        
    #     while  i<n:
    #         s=0
    #         s=i**2+1
    #         i+=1
    #         yield s
    # for i in pingfangjianyi(10):
    #     print(i)
    
    def pingfangjianyi():
        l=[2,3,5,7]
        for j in l :
            s=0
            s=j**2+1
       
            yield s
    for i in pingfangjianyi():
        print(i)
    
    
    
    
    
    l=[2,3,5,7]
    l1=(x**2+1 for x in l )
    print(list(l1))
    l2=[i**2+1 for i in l]
    print(l2)
    
    
    
    生成器表达式和列表推导式的区别
    就是生成器只能迭代一次
    且现用现生成
    而列表生成静态数据
    l=[2,3,5,7]
    l1=(x**2+1 for x in l )
    l[1]=8
    print(list(l1))
    
    
    l=[2,3,5,7]
    l2=[i**2+1 for i in l]
    l[1]=8
    print(l2)
    
    
    [5, 65, 26, 50]
    [5, 10, 26, 50]
    
    
    迭代工具函数
    作用是生成一个个性化的可迭代对象
    函数 zip(iter1[,iter2[......]])
    返回一个zip对象此对象用于生成元组,
    该元组的每个数据来源于参数中的可迭代对象当最小的可迭代对象向不在提供数据
    时迭代结束
    enumerate(iterable[,start])
    生成带索引的枚举对象
    返回对象为索引值(index-value)
    默认索引从零开始
    也可以用start
    指定
    enumerate(sequence, start=0)
    
    
    def hanshu():
        l=[]
        while True:
            x=input('亲输入')
    
    
    
            if x=='':
                break
            l.append(x)
    
        for s in enumerate(l,1):
            print('第%s行:'%s[0],s[1])
    hanshu()
    
    展开全文
  • 请问STL迭代器和设计模式中的迭代器之间的异同点,stl迭代器是否使用了迭代器模式?
  • Python迭代器及自定义迭代器

    千次阅读 多人点赞 2019-05-19 20:47:17
    Python迭代器及自定义迭代器 一、可迭代对象 在Python中,对list、tuple、str等类型的数据可以使用for...in...的循环语法,从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代。 在Python的基本...

    Python迭代器及自定义迭代器

    一、可迭代对象

    在Python中,对list、tuple、str等类型的数据可以使用for...in...的循环语法,从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代。

    在Python的基本数据类型中,列表、元组、字符串、字典都是可迭代的,而整数、浮点数、布尔数都是不可迭代的。

    list_a = [1, 2, 3]
    for a in list_a:
        print(a, end=' ')
    
    tuple_b = ('a', 'b', 'c')
    for b in tuple_b:
        print(b, end=' ')
    
    str_c = 'AKQJ'
    for c in str_c:
        print(c, end=' ')
    
    dict_d = {'BJ': '北京', 'SH': '上海', 'GZ': '广州', 'SZ': '深圳'}
    for d in dict_d:
        print(d, end=' ')

    运行结果:

    1 2 3 a b c A K Q J BJ SH GZ SZ 

    在Python中,把可以通过for...in...这类语句迭代,读取一条数据供我们使用的对象称之为可迭代对象(Iterable)。列表、元组、字符串、字典都是可迭代对象。

    可以使用 isinstance() 判断一个对象是否是 Iterable 对象。

    from collections.abc import Iterable
    
    print(isinstance(list_a, Iterable))

    运行结果:

    True

    二、可迭代对象的本质

    对可迭代对象进行迭代使用的过程,每迭代一次(即在for...in...中每循环一次)都会返回对象中的下一条数据,一直向后读取数据直到迭代了所有数据后结束。

    在这个过程中,我们需要知道每次访问到了第几条数据,以便下一次迭代返回的是下一条数据,不会跳过或者重复返回数据。Python帮我们实现了这个功能,这个功能就是迭代器(Iterator)

    可迭代对象的本质就是提供一个迭代器帮助我们对其进行迭代遍历使用。那Python是怎么实现这些功能的呢?

    在Python中,可迭代对象通过__iter__方法向我们提供一个迭代器,在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据。

    可迭代对象是一个具备了__iter__方法的对象,通过__iter__方法获取可迭代对象的迭代器。

     三、iter()函数与next()函数

    列表、元组、字符串、字典等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。

    list_b = ['ppp', 'yyy', 'ttt', 'hhh', 'ooo', 'nnn']
    iterator_b = iter(list_b)
    print(next(iterator_b))
    print(next(iterator_b))
    print(next(iterator_b))
    print(next(iterator_b))
    print(next(iterator_b))
    print(next(iterator_b))

    运行结果:

    ppp
    yyy
    ttt
    hhh
    ooo
    nnn

    iter(iterable)函数是把可迭代对象的迭代器取出来,内部是调用可迭代对象的__iter__方法,来取得迭代器的。

    next(iterator)函数是通过迭代器取得下一个位置的值,内部是调用迭代器对象的__next__方法,来取得下一个位置的值。

    当我们已经迭代完最后一个数据之后,再次调用next()函数会抛出StopIteration的异常,来告诉我们所有数据都已迭代完成,不用再执行next()函数了。

    for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。

    四、迭代器Iterator

    通过上面的分析,我们已经知道,迭代器用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。

    在使用next()函数的时候,调用的是迭代器对象的__next__方法。所以,我们要想构造一个迭代器,就要实现它的__next__方法。

    同时,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__方法,而__iter__方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__方法返回自身即可。

    也就是说,一个实现了__iter__方法和__next__方法的对象,就是迭代器,迭代器自身也是一个可迭代对象。

    五、自定义迭代器

    迭代器最核心的功能就是可以通过next()函数的调用来返回下一个数据值。

    如果每次返回的数据值不是在一个已有的数据集合中,而是通过程序按照一定的规律计算生成的,那就不用再依赖一个已有的数据集合,也就是说不用再将所有要迭代的数据都一次性缓存下来,这样可以节省大量的存储(内存)空间。

    class FeiboIterator(object):
        """斐波那契数列迭代器"""
    
        def __init__(self, n):
            # 斐波那数列值的个数
            self.n = n
            # 记录当前遍历的下标
            self.index = 0
            # 斐波那数列前面的两个值
            self.num1 = 0
            self.num2 = 1
    
        def __next__(self):
            """被next()函数调用来获取下一个数"""
            if self.index < self.n:
                num = self.num1
                self.num1, self.num2 = self.num2, self.num1 + self.num2
                self.index += 1
                return num
            else:
                raise StopIteration
    
        def __iter__(self):
            """迭代器的__iter__返回自身即可"""
            return self
    
    
    if __name__ == '__main__':
        fb = FeiboIterator(20)
        for num in fb:
            print(num, end=' ')
    

    运行结果:

    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

    上面的代码中,我们自定义一个类,里面实现了__next__和__iter__方法,__next__方法中每次返回的值是我们通过计算得到的结果,所以可以一直使用next()方法。

    当我们通过for...in...循环来遍历迭代斐波那契数列中的前n个数时,会在第n+1次调用next()时抛出StopIteration异常,然后结束for循环,这与Python迭代器的功能是一样的。

    所以,我们已经实现了自定义迭代器。

     

     

    展开全文
  • 迭代器模式的定义非常松散,所以我们可以有多种多样的迭代器实现。总的来说,迭代器模式提供了循环访问一个聚合对象中每个元素的方法,但他没有规定 我们一顺序、倒序还是中序来循环遍历聚合对象。 下面我们分...
  • C++ 迭代器迭代器范围

    千次阅读 2018-03-01 18:55:13
    9.2. 迭代器迭代器范围 在整个标准库中,经常使用形参为一对迭代器的构造函数。在深入探讨容器 操作之前,先来了解一下迭代器迭代器范围。 第 3.4 节首次介绍了 vector 类型的迭代器。每种容器类型都提供若干共 ...
  • 外部迭代器 外部迭代器必须显示的请求迭代器下一个元素。 外部迭代器增加了一些调用的复杂度,但相对也增强了迭代器的灵活性,我们可以手工控制这个迭代的过程或者顺序。 外部迭代器的例子:比较两个数组对应的...
  • C++迭代器(STL迭代器)iterator详解

    千次阅读 2019-04-14 17:48:03
    侵删。...迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。 迭代器按照定义方式分成以下四种。 1) 正向迭代器,定义方法如下: 容器类名...

空空如也

1 2 3 4 5 ... 20
收藏数 79,505
精华内容 31,802
关键字:

迭代器