Python迭代器(Iterator)详解及使用指南

文章目录

  • 一、迭代器
  • 二、可迭代对象
  • 三、iter()、next()函数 for循环大体过程
  • iter()获取一个可迭代对象的迭代器
  • next()获取迭代器的数据
  • 四、自定义"迭代器"
  • __iter__ 方法
  • __next__方法
  • 五、案例升级
  • 六、for…in… 循环的本质
  • 七、并不是只有for循环能接受可迭代对象
  • 八、总结
  • 一、迭代器

    迭代是访问集合元素的一种方式

    迭代器是一个可以记住遍历位置的对象。迭代器对象从第一个元素开始访问,直到所有的元素被访问结束。迭代器只能往前不会后退。

    二、可迭代对象

    能用for循环遍历的对象

    三、iter()、next()函数 for循环大体过程

    iter()获取一个可迭代对象的迭代器

    nums = [1, 2, 3, 4]	# 是可迭代对象
    print(type(nums))	# <class 'list'>
    nums_iter = iter(nums)	# 是迭代器
    print(type(nums_iter))	# <class 'list_iterator'>
    

    next()获取迭代器的数据

    nums = [1, 2, 3, 4]	# 可迭代对象
    nums_iter = iter(nums)	# 迭代器
    num = next(nums_iter)
    print(num)
    num = next(nums_iter)
    print(num)
    

    for循环的过程可以通过上面的iter()和next()函数来实现,即:
    1、先调用iter(),将nums当作实参,得到nums这个可迭代对象的迭代器
    2、调用next(),将上一步得到的迭代器 进行取值
    3、将上一步取出来的值 赋值给num这个变量
    4、执行for循环体中的代码,print(num)
    5、重复执行2/3/4步,当nums中所有数据都获取完毕后,会在下一次调用next的时候产生Stopiteration异常。只不过 for循环中自带了异常处理,当它遇到Stopiteration异常的时候,会自动结束for循环

    四、自定义"迭代器"

    iter 方法

    迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用 next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。

    实际上,在使用 next()函数的时候,调用的就是迭代器对象的 next 方法(Python2中是对象的next()方法)。

    所以想要构造一个迭代器,就要实现它的 __next__方法。

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

  • 一个实现了__iter__方法和__next__方法的对象,就是迭代器
    可以使用 isinstance() 判断一个对象是否是Iterator对象
  • from collections.abc import Iterable
    
    class MyList(object):
    	def __init__(self):
    		self.container = []
    	
    	def __iter__(self):	# 只要有此方法最下面的结果就是True
    		pass
    
    	def add(self, item):
    		self.container.append(item)
    
    myList = MyList()
    mylist.add(11)
    mylist.add(22)
    mylist.add(33)
    
    print(isinstance(mylist, Iterable))	# 如果结果是True 则表示mylist一定是可迭代对象,否则是不可迭代对象
    

    总结:如果定义类时,有__iter__方法,那么这个类创建出来的对象一定是可迭代对象

    __next__方法

    from collections.abc import Iterable
    from collections.abc import Iterator
    
    class MyList(object):
    	"""自定义的一个可迭代对象"""
    	def __init__(self):
    		self.items = []
    
    	def add(self, val):
    		self.items.append(val)
    
    	def __iter__(self):
    		# 这个方法有两个功能
    		# 1.标记用当前类创建出来的对象一定是 可迭代对象
    		# 2.当调用iter()函数的时候 这个方法会被自动调用 它返回自己指定的哪个迭代器
    		return MyIterator()
    
    class MyIterator(object):
    	"""自定义的供上面可迭代对象使用的一个迭代器"""
    	def __init__(self):
    		pass
    
    	def __next__(self):
    		# 这个方法有两个功能
    		# 1.标记当前类创建出来的对象(当然还必须有__iter__方法)一定是迭代器
    		# 2.当调用next()函数的时候 这个方法会被自动调用 它返回一个数据
    		pass
    
    	def __iter__(self):
    		pass
    
    mylist = MyList()	# 可迭代对象
    mylist_iter = iter(mylist)	# 当对mylist调用iter()函数的时候,会自动调用MyList类中的__iter__方法,返回的就是mylist这个可迭代对象的迭代器
    
    print("mylist是否是可迭代对象", isinstance(mylist, Iterable))	# True
    print("mylist是否是迭代器", isinstance(mylist, Iterator))	# False
    
    print("mylist_iter是否是可迭代对象", isinstance(mylist_iter, Iterable))	# True
    print("mylist_iter是否是迭代器", isinstance(mylist_iter, Iterator))	# True
    
    # next(mylist_iter)
    
  • 总结:__iter__方法、__next__方法 与 iter()函数、next()函数的区别是,
    1. 当对一个可迭代对象调用iter()函数时,它会自动调用这个可迭代对象的__iter__方法,这个方法返回的对象当作迭代器
    2. 当对一个迭代器对象调用 next()函数时,它会自动调用这个迭代器对象的__next__方法,这个方法返回想要那个数据
    3. 迭代器对象 一定是 可迭代对象;可迭代对象 不一定是 迭代器
  • 五、案例升级

    from collections.abc import Iterable
    from collections.abc import Iterator
    
    class MyList(object):
    	"""自定义的一个可迭代对象"""
    	def __init__(self):
    		self.items = []
    		self.current = 0
    	
    	def add(self, val):
    		self.items.append(val)
    
    	def __iter__(self):
    		return self
    
    	def __next__(self):
    		if self.current < len(self.items):
    			item = self.items[self.current]
    			self.current += 1
    			return item
    		else:
    			raise StopIteration	# 抛出异常(不返回None是因为,for循环是一个已实现的功能,它自带iter、next函数,并且带有异常判断,通过这个异常判断来决定是否还需要继续获取迭代器的数据,如果用None来表示数据已获取完毕,但是for循环的代码依然用的异常来判断而不是None,所以for循环会产生死循环)
    
    
    if __name__ == '__main__':
    	mylist = MyList()
    	mylist.add(1)
    	mylist.add(2)
    	mylist.add(3)
    	mylist.add(4)
    	mylist.add(5)
    	
    	# mylist_iter = iter(mylist)
    	# print(next(mylist_iter))
    
    	# for num in mylist:
    	#	print(num)
    	nums = list(mylist)	# list在创建一个新的列表的时候,只要是 可迭代对象 就可以放到list中当作实参
    	print(nums)
    

    六、for…in… 循环的本质

    1.先调用 iter()函数,它会自动调用可迭代对象中的 __iter__方法,此方法返回这个可迭代对象的 迭代器对象
    2.对获取到的迭代器不断调用 next()函数,它会自动调用迭代器中的 __next__方法来获取下一个值
    3.当遇到 StopIteration异常后循环结束

    七、并不是只有for循环能接受可迭代对象

    除了for循环外,list、tuple等也能接收

    八、总结

    1.凡是可作用于 for循环的对象都是 Iterable 类型;
    2.但是可作用于 next()函数的对象都是 Iterator 类型;
    3.集合数据类型如 list、dict、str 等是 Iterable 但不是 Iterator, 不过可以通过 iter() 函数获得一个 Iterator 对象
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » Python迭代器(Iterator)详解及使用指南

    发表评论