- 外文名
- iterator
- 别 称
- 游标卡尺
- 提出者
- 张康健
- 中文名
- 迭代器
- 适用领域范围
- IT行业
-
迭代器
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))
-
C++(标准库):26---STL迭代器之(迭代器的5大种类(输出迭代器、输入迭代器、向前迭代器、双向迭代器、随机...
2020-04-13 12:43:19一、迭代器的头文件 所有的容器都定义有自己的iterator类型,因此如果单单使用容器,只需要包含对应容器的头文件即可 不过有些特殊的iterator,被定义在头文件<iterator>中 二、迭代器介绍 类似于容器,...一、迭代器的头文件
- 所有的容器都定义有自己的iterator类型,因此如果单单使用容器,只需要包含对应容器的头文件即可
- 不过有些特殊的iterator,被定义在头文件<iterator>中
二、迭代器介绍
- 类似于容器,迭代器也定义了一组公共操作:
- 一些操作所有迭代器都支持
- 另外一些只有特定类型的迭代器才支持
- 例如,ostream_iterator只支持递增、解引用、赋值。vector、string等容器的迭代器除了这些操作之外,还支持递减、关系、算术运算
迭代器的继承关系
- 可以参阅:https://blog.csdn.net/qq_41453285/article/details/103540156
- 高层类型的迭代器支持底层类别迭代器的所有操作
三、五大类迭代器
输入迭代器(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)函数获取可迭代对象的数据 迭代器函数iter和next 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迭代器
2016-04-19 04:31:53请问STL迭代器和设计模式中的迭代器之间的异同点,stl迭代器是否使用了迭代器模式? -
Python迭代器及自定义迭代器
2019-05-19 20:47:17Python迭代器及自定义迭代器 一、可迭代对象 在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迭代器的功能是一样的。
所以,我们已经实现了自定义迭代器。
-
js迭代器之倒序访问迭代器及终止迭代器
2017-01-20 16:53:55迭代器模式的定义非常松散,所以我们可以有多种多样的迭代器实现。总的来说,迭代器模式提供了循环访问一个聚合对象中每个元素的方法,但他没有规定 我们一顺序、倒序还是中序来循环遍历聚合对象。 下面我们分... -
C++ 迭代器和迭代器范围
2018-03-01 18:55:139.2. 迭代器和迭代器范围 在整个标准库中,经常使用形参为一对迭代器的构造函数。在深入探讨容器 操作之前,先来了解一下迭代器和迭代器范围。 第 3.4 节首次介绍了 vector 类型的迭代器。每种容器类型都提供若干共 ... -
js迭代器——外部迭代器
2017-01-19 17:53:04外部迭代器 外部迭代器必须显示的请求迭代器下一个元素。 外部迭代器增加了一些调用的复杂度,但相对也增强了迭代器的灵活性,我们可以手工控制这个迭代的过程或者顺序。 外部迭代器的例子:比较两个数组对应的... -
C++迭代器(STL迭代器)iterator详解
2019-04-14 17:48:03侵删。...迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。 迭代器按照定义方式分成以下四种。 1) 正向迭代器,定义方法如下: 容器类名...
-
前端架构师-速成
-
国家注册信息安全工程师体系课程(CISP-PTE)
-
为何组件的data必须是一个函数
-
(新)备战2021软考系统集成顺利通关套餐
-
朱有鹏老师嵌入式linux核心课程2期介绍
-
严格劣势策略与弱劣势策略
-
(新)备战2021软考信息安全工程师基础知识套餐
-
计算机病毒分为哪三类
-
2021年R2移动式压力容器充装考试及R2移动式压力容器充装考试APP
-
opencv学习十九:膨胀与腐蚀
-
备战2021软考网络规划设计师历年真题套餐
-
FFmpeg4.3黄金系列课程:c++版
-
Soul网关插件之Sofa
-
小学数学知识点大全 (简单的统计)<NLP 颜色标记>
-
IIR数字滤波器的设计及结构.pdf
-
06 Python编程语言基础技术框架(2).mp4
-
萝丽双路双向电调 - B版固件(双路独立).rar
-
(新)备战2021软考网络工程师历年真题培训套餐
-
soul网关学习day04
-
智联万物,京东IoT技术创新与实践