python迭代器和推导

  1. 如果对象时实际保存的序列或是在迭代工具上下文中(例如,for循环)一次产生一个结果的对象,那么就看作是可迭代的。总之,可迭代对象包括实际序列,以及能按照需求计算的虚拟序列。术语可迭代对象与迭代器在指代支持迭代的对象的时候,常常是可以互换的。一般倾向用可迭代对象(iterable)来指代一个支持iter调用的对象,同时用迭代器(iterator)来指代一个支持next(I)调用的对象。生成器指代自动支持迭代协议的对象,因此生成器本身就是可迭代对象。
  2. 内置函数next会自动调用一个对象的__next__方法。for循环在开始时,会首先把可迭代对象传入内置函数iter,并由此拿到一个迭代器,迭代器对象有着所需的next方法。
  3. 一些对象即使迭代上下文的工具(它们可以主动发起迭代),也是可迭代对象(他们的返回值可迭代),包括生成器表达式,以及map、zip内置函数。
  4. 列表以及很多其他的内置对象,由于自身不是迭代器,对这样的对象,我们必须调用iter来启动迭代。
  5. 我们必须把某些返回结果包装到一个list调用中,才能一次性看到他们的值。
    R=range(5)
    I=iter(R)
    next(I)  #0
    next(I) #1
    list(R)  #[0,1,2,3,4]
  6. 列表推导
    L=[1,2,3,4,5]
    L=[x+10 for x in L]#[11,12,13,14,15]
    
    lines=[line.rstrip() for line in open('script.py')]#可用于文件
    
    #添加if语句
    lines=[line.rstrip() for line in open(script2.py') if line[0]=='p']
    
    [x+y for x in 'abc' for y in 'lmn']#嵌套循环,['al','am','an','bl','bm','bn','cl','cm','cn']

    集合推导和字典推导同理。

  7. 其他迭代上下文。map是一个内置函数,作用是把一个函数调用应用于传入的可迭代对象的每一项。map类似于列表推导,但是他更有局限性,因为他必须传入一个函数而不是一个任意的表达式。它本身还会返回一个可迭代对象。sorted能够排序可迭代对象中的各项;zip能够组合可迭代对象中的各项;enumerate能够把可迭代对象中的项和他们的相对位置进行匹配;filter能够按照一个函数是否为正来选择可迭代中的项;reduce能够针对可迭代对象中的成对的项来运行一个函数;zip、enumrate和filter和map返回一个可迭代对象。
  8. 实际上python的内置工具集中所有能够从左到右扫描一个对象的工具,都被定义为在主体对象上使用了迭代协议。例如list、tuple、字符串的join方法、序列赋值、in成员测试、分片赋值等。
  9. 重载运算符__iter__、__next__和在__iter__使用yield实现多变扫描:
    class Squares:
        def __init__(self,start,stop):
            self.value=start-1
            self.stop=stop
        def __iter__(self):
            return self  #本身就是可迭代对象
        def __next__(self):
            if self.value==self.stop: #迭代终止条件
                raise StopIteration  
            self.value+=1
            return self.value**2
    
    
    #s=Squares(1,3)  iter(s)返回自己,只能单边扫描
    class SkipObject:
        def __init__(self,wrapped):
            self.wrapped=wrapped
        def __iter__(self):
            return SkipIterator(self.wrapped)#每次调用都产生新迭代器
    
    
    class SkipIterator:
        def __init__(self,wrapped):
            self.wrapped=wrapped
            self.offset=0
        def __next__(self):
            if self.offset>=len(self.wrapped):
                raise StopIteration
            else:
                item=self.wrapped[self.offset]
                self.offset+=2
                return item
    
    #支持多遍扫描
    class Squares:
        def __init__(self,start,stop):
            self.value=start-1
            self.stop=stop-1
        def __iter__(self):
            for value in range(self.start,self.stop+1):
                yield value**2
    
    #结合yield生成器,自动含有__next__方法。又如:
    
    class SkipObject:
        def __init__(self,wrapped):
            self.wrapped=wrapped
        def __iter__(self):
            offset=0
            while offset<len(self.wrapped):
                item=self.wrapped[offset]
                offset+=2
                yield item
    
    #也支持多遍扫描
原文地址:https://www.cnblogs.com/biwangwang/p/11330174.html