Python大杀器--迭代器、生成器

要判断一个Pythonista编写的代码够不够pythonic,一个很重要的标准就是看他能不能灵活运用迭代器。
首先要介绍一下什么是迭代器:在python中有两种循环语句,while和for。通常我们可以以c风格来使用它们,但是python额外提供了另外一种更为方便和高效的使用方式。通俗的来说就是边生产边消费。代码易读性和简洁高效性之争
首先要介绍一下几个概念之间得差异:

  1. 可迭代对象: 除了列表、元组、字符串、元组、集合、字典等序列外,只要实现了__iter__和__getitem__中任意一个方法的对象都是可以进行迭代的。不同的是,在进行迭代的时候解释器会调用iter函数,iter函数会检查对象是否实现了__iter__方法,如果实现了就会调用它得到一个生成器,如果没有实现__iter__方法但是实现了 __getitem__方法,Python 会创建一个迭代器, 尝试按顺序(从索引 0 开始) 获取元素。isinstance(objiect, Iterable)只会检测__iter__方法,忽略了__getitem__方法。

    # coding=utf8
    from collections import Iterable
    
    list_a = [3, 3, 45, 6]
    dict_b = {'a': 'ji', 'b': 'ok', 'c': 'illegall'}
    set_c = {'df', 'fdk', 'lo'}
    tuple_d = ('jfk', 'dj', 'ilsl')
    str_e = 'jkilljls'
    isinstance(list_a, Iterable)  # True 列表是可迭代对象
    isinstance(dict_b, Iterable)  # True 字典是可迭代对象
    isinstance(set_c, Iterable)  # True 集合是可迭代对象
    isinstance(tuple_d, Iterable)  # True 元组是可迭代对象
    isinstance(str_e, Iterable)  # True 字符串是可迭代对象
    

    在这里插入图片描述

    class Queue:
    	def __init__(self, q):
        	self.queue = q
    
    	def __iter__(self):
        	for item in self.queue:
            	yield item
    
    	# def __getitem__(self, item):
    	#     return self.queue[item]
    
    queue = Queue([1, 4, 5, 8])
    print(isinstance(queue, Iterable))  #True 只要实现了__iter__方法则该对象就是可迭代对象,还有其他情况见后面
    
    class Queue:
    	def __init__(self, q):
        	self.queue = q
    
    	#def __iter__(self):
    	#    for item in self.queue:
     	#        yield item
    
    	def __getitem__(self, item):
      		return self.queue[item]
    
    queue = Queue([1, 4, 5, 8])
    isinstance(queue, Iterable)  #False 没有实现__iter__方法,但是实现了__getitem__方法也是可迭代对象
    							 #Iterable只对__iter__方法进行检测
    for item in queue:  # 只要实现了__iter__和__getitem__中的任意一个,则该对象都是可以进行迭代的。
    	print(item)   
    
  2. 迭代器: 实现了next方法和__iter__方法的对象,且next方法实现了迭代协议,__iter__方法返回迭代器。
    如下是一个迭代器类,可以产生迭代器对象,对迭代器对象调用iter函数返回迭代器类自身,迭代环境中自动调用__next__方法。

    class iter:
    	def __init__(self, data):
    		self.data = data
    		self.now = 0
    	
    	def __iter__(self):
    		return self
    	
    	def __next__(self):
    		if self.now < data:
    			self.now += 1
    			return (self.now-1)**2
    		 raise StopIteration 
    
  3. 生成器:生成器是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和next方法),不需要再手动实现两方法。
    3.1 生成器表达式:可以使用表达式来得到生成器
    使用生成器表达式可以非常轻松的得到生成器,只要将列表解析式中的方括号换成圆括号就可以了。

    (x for x in range(5))  # iterator
    

    3.2 生成器函数:在函数中使用关键词yield得到生成器

    def gen(num):
    	cou = 0
    	while cou < num:
    		yield cou
    		cou += 1
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章