【Python CookBook】第四章 迭代器与生成器

  1. 迭代器,可迭代对象,迭代器协议,生成器;next()函数,_iter_()函数,yield语句;以及如何自己创建一个迭代器或者可迭代对象,见:迭代器,生成器与协程

  2. 反向迭代:reversed()函数。反向迭代需要对象的大小可预先确定或者本身实现了_reversed_()函数才行。

    >>> a = [1, 2, 3, 4]
    >>> for x in reversed(a):
    ... print(x)
    ...
    4321
    
  3. 需要将生成器暴露外部状态,可将实现一个类,将生成器函数放到_iter_()函数中。

  4. 迭代器切片:itertools.islice()。迭代器和生成器不能使用标准的切片操作,因为它们的长度事先我们并不知道。如果需要切片10到后面所有,则(c, 10, None)。

    >>> import itertools
    >>> for x in itertools.islice(c, 10, 20):
    ... print(x)
    ...
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
  5. 跳过可迭代对象的开始部分:itertools.dropwhile(),参数是一个函数对象和一个可迭代对象,它会返回一个迭代器对象,丢弃原有序列中直到函数返回Flase 之前的所有元素,然后返回后面所有元素。

    >>> from itertools import dropwhile
    >>> with open('/etc/passwd') as f:
    ... for line in dropwhile(lambda line: line.startswith('#'), f):
    ... print(line, end='')
    ...
    nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
    root:*:0:0:System Administrator:/var/root:/bin/sh
    ...
    
  6. 集合元素的全排列:itertools.permutations()

    >>> items = ['a', 'b', 'c']
    >>> from itertools import permutations
    >>> for p in permutations(items):
    ... print(p)
    ...
    ('a', 'b', 'c')
    ('a', 'c', 'b')
    ('b', 'a', 'c')
    ('b', 'c', 'a')
    ('c', 'a', 'b')
    ('c', 'b', 'a')
    

    可指定长度的全排列:

    >>> for p in permutations(items, 2):
    ... print(p)
    ...
    ('a', 'b')
    ('a', 'c')
    ('b', 'a')
    ('b', 'c')
    ('c', 'a')
    ('c', 'b')
    
  7. 集合元素的全部组合:itertools.combinations()

    >>> from itertools import combinations
    >>> for c in combinations(items, 3):
    ... print(c)
    ...
    ('a', 'b', 'c')
    >>> for c in combinations(items, 2):
    ... print(c)
    ...
    ('a', 'b')
    ('a', 'c')
    ('b', 'c')
    >>> for c in combinations(items, 1):
    ... print(c)
    ...
    ('a',)
    ('b',)
    ('c',)
    

    itertools.combinations_with_replacement() 允许同一个元素被选择多次。

  8. 迭代时返回索引和值:enumerate()。可指定索引的初始值。

  9. 同时迭代多个序列:zip()函数。zip() 可以接受多于两个的序列的参数,zip()返回的是迭代器。迭代长度跟参数中最短序列长度一致。

    >>> xpts = [1, 5, 4, 2, 10, 7]
    >>> ypts = [101, 78, 37, 15, 62, 99]
    >>> for x, y in zip(xpts, ypts):
    ... print(x,y)
    ...
    1 101
    5 78
    4 37
    2 15
    10 62
    7 99
    

    或者使用itertools.zip_longest()来和最长序列长度一致,fillvalue指定缺省值。

    >>> from itertools import zip_longest
    >>> for i in zip_longest(a,b):
    ... print(i)
    ...
    (1, 'w')
    (2, 'x')
    (3, 'y')
    (None, 'z')
    >>> for i in zip_longest(a, b, fillvalue=0):
    ... print(i)
    ...
    (1, 'w')
    (2, 'x')
    (3, 'y')
    (0, 'z')
    >>>
    

    更帅的生成字典的方式:

    headers = ['name', 'shares', 'price']
    values = ['ACME', 100, 490.1]
    s = dict(zip(headers,values))
    
  10. 迭代多个集合里的所有元素:itertools.chain()

    >>> from itertools import chain
    >>> a = [1, 2, 3, 4]
    >>> b = ['x', 'y', 'z']
    >>> for x in chain(a, b):
    ... print(x)
    ...
    1234xyz
    
  11. 生成器函数是一个实现管道机制的好办法。yield 语句作为数据的生产者而for 循环语句作为数据的消费者。

  12. 展开嵌套的序列成一个单层列表:yield from。下面为模板:

    from collections import Iterable
    
    # 额外的参数ignore_types 和检测语句isinstance(x, ignore_types) 用来将字符串和字节排除在可迭代对象外,防止将它们再展开成单个的字
    def flatten(items, ignore_types=(str, bytes)):
        for x in items:
            if isinstance(x, Iterable) and not isinstance(x, ignore_types):
                yield from flatten(x)
        	else:
       			yield x
    
    items = [1, 2, [3, 4, [5, 6], 7], 8]
    # Produces 1 2 3 4 5 6 7 8
    for x in flatten(items):
    	print(x)
    
  13. 合并多个有序序列:heapq.merge()。而且其返回迭代器,开销小。

    >>> import heapq
    >>> a = [1, 4, 7, 10]
    >>> b = [2, 5, 6, 11]
    >>> for c in heapq.merge(a, b):
    ... print(c)
    ...
    1 2 4 5 6 7 10 11
    
  14. iter 函数一个鲜为人知的特性是它接受一个可选的callable 对象和一个标记(结尾) 值作为输入参数。当以这种方式使用的时候,它会创建一个迭代器,这个迭代器会不断调用callable 对象直到返回值和标记值相等为止。故处理数据时尽量用迭代器代替while True。

    >>> import sys
    >>> f = open('/etc/passwd')
    >>> for chunk in iter(lambda: f.read(10), ''):
    ... 	n = sys.stdout.write(chunk)
    ...
    nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
    root:*:0:0:System Administrator:/var/root:/bin/sh
    daemon:*:1:1:System Services:/var/root:/usr/bin/false
    _uucp:*:4:4:Unix to Unix Copy Protocol:/var/spool/uucp:/usr/sbin/uucico
    ...
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值