【Python生成器与迭代器的区别】

目录

一、迭代

二、迭代器

1)创建迭代器——两种方法

iter()方法

利用()和range结合使用

2)具体案例

3、生成器

4、二者的异同

1)、共同点

2)、不同点

a、语法上

b、用法上


一、迭代

首先理解一下迭代,迭代简单地理解就是通过循环的方式遍历一个多元素容器,这个容器可以是列表可以是元组等序列数据类型。迭代遍历容器每一个元素,对每一个元素进行操作,比如打印。

# 1、普通迭代
print("--------------------------普通迭代--------------------------")
for i in [1, 2, 3, 4, 5]:
	print(i)

--------------------------普通迭代--------------------------
1
2
3
4
5

二、迭代器

迭代器其实就是将一个特殊的类实例化后得到的类对象,这个特殊的类特殊之处就在于一定含有两个方法分别是__iter__()和__next__()方法。__iter__()方法是返回类对象自身,__next__()方法则是根据函数和上一个元素计算出下一个元素值并且通过return的方法返回值

首先__iter__()方法只会调用一次,通过iter()方法得到函数的迭代器(其实就是先将所有的元素计算出来了,然后将),然后__next__()则会被调用n次,用于遍历所有的元素,这个遍历只能往前而不能向后

1)创建迭代器——两种方法

iter()方法

print("创建迭代器")
l = [1,2,3,4]
print(iter(l))

创建迭代器
<list_iterator object at 0x00000288A3300C88>

利用()和range结合使用

2)具体案例

class Fib(object):
	def __init__(self, max):
		super(Fib, self).__init__()
		self.max = max

	def __iter__(self):
		self.a = 0
		self.b = 1
		# __iter__()方法返回自身
		return self

	def __next__(self): # __next__()方法则是根据当前元素的值和设定的运算函数计算得到下一个函数
		fib = self.a
		if fib > self.max:
			raise StopIteration
		self.a, self.b = self.b, self.a + self.b
		return fib

# 定义一个main函数,循环遍历每一个菲波那切数
def main1():
	# 20以内的数
	fib = Fib(20)
	for i in fib: #
		print(i)

# 定义一个main2函数,循环遍历每一个菲波那切数
def main2():
	# 20以内的数
	fib = Fib(20)
	try:
		print(next(fib))
	except:
		print("所有元素迭代完毕!!!")


# 测试
if __name__ == '__main__':
	print("---------------------------------for 遍历迭代器所有元素值-------------------------")
	main1()
	print("---------------------------------next方法 遍历迭代器所有元素值-------------------------")
	main1()

解释说明:

在本类的实现中,定义了一个_iter_(self)方法,这个方法是在for循环遍历时被iter()调用,返回一个迭代器。因为在遍历的时候,是直接调用的python内置函数iter() ,由iter()通过调用_iter_(self)获得对象的迭代器。有了迭代器,就可以逐个遍历元素了。而逐个遍历的时候,也是使用内置的next()函数通过调用对象的_next_(self)方法对迭代器对象进行遍历。所以要实现_iter_(self)_next_(self)这两个方法。

而且因为实现了_next_(self)方法,所以在实现_iter_(self)的时候,直接返回self就可以。

总结一句话就是:

在循环遍历自定义容器对象时,会使用python内置函数iter()调用遍历对象的_iter_(self)获得一个迭代器,之后再循环对这个迭代器使用next()调用迭代器对象的_next_(self)

---------------------------------for 遍历迭代器所有元素值-------------------------
0
1
1
2
3
5
8
13
---------------------------------next方法 遍历迭代器所有元素值-------------------------
0
1
1
2
3
5
8
13

3、生成器

生成器其实就是一个特殊的迭代器。主要的特点是通过yield来返回值,边计算边返回值,大大减少了内存。生成器可以理解为是一个函数

# 菲波那切数列
def Fib(max):
	n, a, b = 0, 0, 1
	while n < max:
		yield b
		a, b = b, a + b
		n = n + 1
	return '亲!没有数据了...'


# 调用方法,生成出10个数来
f = Fib(10)
# 使用一个循环捕获最后return 返回的值,保存在异常StopIteration的value中
while True:
	try:
		x = next(f)
		print("f:", x)
	except StopIteration as e:
		print("生成器最后的返回值是:", e.value)
		break

----------------------生成器---------------
f: 1
f: 1
f: 2
f: 3
f: 5
f: 8
f: 13
f: 21
f: 34
f: 55
生成器最后的返回值是: 亲!没有数据了...

4、二者的异同

1)、共同点

  • 生成器是一种特殊的迭代器

2)、不同点

a、语法上

  • 生成器是通过函数的形式中调用 yield 或()的形式创建的
  • 迭代器可以通过 iter() 内置函数创建

b、用法上

  • 生成器在调用next()函数或for循环中,所有过程被执行,且返回值,边计算边返回
  • 迭代器在调用next()函数或for循环中,所有值被返回,没有其他过程或说动作。

猜你喜欢

转载自blog.csdn.net/qq_45769063/article/details/120679112
今日推荐