面试题-python 什么是迭代器?

前言

python 里面有 3 大神器:迭代器,生成器,装饰器。在了解迭代器之前,需弄清楚2个概念:
1.什么是迭代
2.什么是可迭代对象

迭代

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)
在Python中,迭代是通过for … in来完成的。

"""
列表a中大于0的值,得到新的列表
"""
a = [1, -2, 3, -5, 7]

c = []
for i in a:
if i > 0:
c.append(i)
print(c) # [1, 3, 7]

Iterable 可迭代对象

在python 里面 list、tuple、dict、set、str 这些基础数据类型都是可以作用于for循环的。
可以使用 isinstance() 判断一个对象是否是 Iterable 对象:

"""
isinstance 判断实例类型
Iterable 可迭代对象
"""

from collections import Iterable

a = 12
print(isinstance(a, Iterable))
b = "abc"
print(isinstance(b, Iterable))
c = [1, 2, 3]
print(isinstance(c, Iterable))
d = (1, 2, 3)
print(isinstance(d, Iterable))
e = {1, 2, 3}
print(isinstance(e, Iterable))
f = {"key": 1}
print(isinstance(f, Iterable))

运行结果
False
True
True
True
True
True

除了上面的6种基础的是可迭代的,还有一类是 生成器(generator),包括生成器和带yield的 生成器函数

Iterator 迭代器

可以被 next() 函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可以使用isinstance() 判断一个对象是否是 Iterator 对象:

from collections import Iterable, Iterator

a = 12
print(isinstance(a, Iterator))
b = "abc"
print(isinstance(b, Iterator))
c = [1, 2, 3]
print(isinstance(c, Iterator))
d = (1, 2, 3)
print(isinstance(d, Iterator))
e = {1, 2, 3}
print(isinstance(e, Iterator))
f = {"key": 1}
print(isinstance(f, Iterator))
结果返回
False
False
False
False
False
False

list、dict、str虽然是可迭代对象 (Iterable),却不是 迭代器 (Iterator), 可以使用 iter() 函数,变成迭代器

# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

from collections import Iterable, Iterator

b = "abc"
new_b = iter(b)

print(new_b)
print(isinstance(new_b, Iterator))

c = [1, 2, 3]
print(iter(c))
print(isinstance(iter(c), Iterator))

d = (1, 2, 3)
print(iter(d))
print(isinstance(iter(d), Iterator))

e = {1, 2, 3}
print(iter(e))
print(isinstance(iter(e), Iterator))

f = {"key": 1}
print(iter(f))
print(isinstance(iter(f), Iterator))

迭代器 iter() 和 next()

迭代器有两个基本的方法:iter() 和 next()。
使用iter() 创建一个迭代器后,可以使用next() 输出迭代器的下一个元素

a = [1, 2, 3, 4]
it = iter(a) # 创建迭代器对象
print(next(it)) # 输出迭代器的下一个元素

print(next(it))

输出结果
1
2

也可以使用 for 来遍历

a = [1, 2, 3, 4]
it = iter(a) # 创建迭代器对象
for x in it:
print(x, end=" ")
输出结果
1 2 3 4

如果用next() 函数取值,一直取到没有了,那就会抛出”StopIteration” 异常

a = [1, 2, 3, 4]
it = iter(a) # 创建迭代器对象

print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it)) # StopIteration

运行结果

1
2
3
4
Traceback (most recent call last):
File "D:/xx.py", line 9, in <module>
print(next(it))
StopIteration

如果用next()输出全部值,可以加个try…expect

a = [1, 2, 3, 4]
it = iter(a) # 创建迭代器对象

while True:
try:
print(next(it))
except StopIteration:
break

创建迭代器

把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__()__next__()
__iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了__next__() 方法并通过 StopIteration 异常标识迭代的完成。
__next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
创建一个返回数字的迭代器,初始值为 1,逐步递增 1:

class MyNumbers:

def __iter__(self):
self.a = 1
return self

def __next__(self):
x = self.a
self.a += 1
return x

myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
输出结果
1
2
3

StopIteration

StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

class MyNumbers:

def __iter__(self):
self.a = 1
return self

def __next__(self):
if self.a <= 3:
x = self.a
self.a += 1
return x
else:
raise StopIteration

myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
# 第4次会抛异常
print(next(myiter))

在 3 次迭代后停止执行

斐波那契数列

斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13,特别指出:第0项是0,第1项是第一个1。从第三项开始,每一项都等于前两项之和
求出小于100 的所有的斐波那契数列

# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

class MyNumbers:

def __iter__(self):
self.n1 = 0
self.n2 = 1
self.count = 1
return self

def __next__(self):
self.n1, self.n2 = self.n2, self.count
self.count = self.n1 + self.n2
if self.count <= 100:
return self.count
else:
raise StopIteration

myclass = MyNumbers()
myiter = iter(myclass)
while True:
try:
print(next(myiter), end=" ")
except StopIteration:
break

输出结果:2 3 5 8 13 21 34 55 89

2021年第六期《python接口自动化+测试开发》课程,1月9号开学(火热报名中!)

本期上课时间:1月9号-4月18号,每周六、周日晚上20:30-22:30

(0)

相关推荐

  • 一文掌握 Python 迭代器的原理

    理解迭代器是每个严肃的 Python 使用者学习 Python 道路上的里程碑.本文将从零开始,一步一步带你认识 Python 中基于类的迭代器. 相较于其他编程语言,Python 的语法是优美而清晰 ...

  • Python学习——for循环,生成器,迭代器详解

    文章目录 Python的for循环 for循环示例 List 列表循环 dict 字典循环 列表生成式 生成器 列表式生成器 函数式生成器 生成器式生产者消费者模型 迭代器 什么是迭代器 再论for循 ...

  • Python迭代器

    迭代器是可以迭代的对象. 在本教程中,您将了解迭代器的工作原理,以及如何使用__iter__和__next__方法构建自己的迭代器. 迭代器在Python中无处不在. 它们优雅地实现在循环,推导,生成 ...

  • 【Python 第75课】可迭代对象和迭代器

    for 循环是我们在 Python 里非常常用的一个语法,但你有没有思考过 for 循环是怎样实现的? 如果你以前接触过 C++,应该会知道类似 for (int i = 0; i < 100; ...

  • 面试题-python 浅拷贝和深拷贝(copy模块)

    前言 面试的时候经常会问到深拷贝和浅拷贝,那么python的深拷贝和浅拷贝有什么区别呢? 思考题 先来看 2 个简单的案例, 对元素 a/aa 重新赋值一个新的变量 b/bb 后,改变原来 a/aa ...

  • 面试题-python 什么是生成器(generator)?

    前言 在 Python 中,带有 yield 的函数在 Python 中被称之为 generator(生成器). 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器 ...

  • 面试题-python 如何读取一个大于 10G 的txt文件?

    前言 用python 读取一个大于10G 的文件,自己电脑只有8G内存,一运行就报内存溢出:MemoryError python 如何用open函数读取大文件呢? 读取大文件 首先可以自己先制作一个大 ...

  • 面试题-python 什么是闭包(closure)?

    前言 前面学了装饰器,那么闭包和装饰器有什么区别呢? 闭包传递的是变量,而装饰器传递的是函数对象,只是传的参数内容不一样,闭包的概念包含了装饰器,可以说装饰器是闭包的一种,它只是传递函数对象的闭包. ...

  • 面试题-python 垃圾回收机制?

    前言 简历上写着熟悉 python 面试官上来就问:说下python 垃圾回收机制?一盆冷水泼过来,瞬间感觉 python 不香了. Python中,主要通过引用计数(Reference Counti ...

  • Python生成器和迭代器有什么用?

    当我们学习Python的时候,会遇到很多专业的术语及工具,而对于这些很多人并不是很了解,比如说生成器和迭代器,Python的生成器和迭代器有什么区别?这是很多人都比较疑惑的问题,我们来看看吧. 迭代器 ...

  • Python学习之迭代器和生成器有什么不同?

    迭代器和生成器区别是什么?相信很多人在初学Python的时候对它们都很好奇,接下来我们一起来看看它们的区别吧. 迭代器是一个更抽象的概念,任何对象,如果它的类有next方法和iter方法返回自己的本身 ...

  • Python基础篇--迭代器,生成器和装饰器

    迭代 遵循迭代器协议时,需要Python迭代器对象支持两种方法. __iter__返回迭代器对象本身.这用于for 和in语句. __next__方法从迭代器返回下一个值.如果没有其他项目要返回,则应 ...

  • Python生成器与迭代器

    Python生成器与迭代器,Python生成器与迭代器对于喜欢Python开发的小伙伴们来说应该是不陌生的,不了解的小伙伴也没有关系,本篇文章小编就给小伙伴们详解一下Python生成器与迭代器,感兴趣 ...