python cookbook 迭代器与生成器

代理迭代

  a = [1, 2, 3]
  for i in iter(a):
    print(i)
  for i in a.__iter__():
    print(i)

这里的两个方法是一样的,调用iter()其实就是简单的调用了对象的__iter__()方法。

使用生成器创建新的迭代器

  def frange(start, stop, increment):
    x = start
    while x < stop:
      yield x
      x += increment
  for n in frange(0, 4, 0.5):
    print(n)
  print(list(frange(0, 4, 0.5)))

看下面这个

>>> def countdown (n):
...     print ('Starting to count from', n)
...     while n > 0:
...        yield n
...        n -= 1
...     print ('Done!')
...
>>> # Create the generator, notice no output appears
>>> c = countdown(3)
>>> c
<generator object countdown at 0x1006a0af0>>>> next(c)
Starting to count from 3
3>>> next(c)
2>>> next(c)
1>>> next(c)
Done!
Traceback (most recent call last):
File "<stdin>", line 1, in < module >
StopIteration

一个生成器函数主要特征是它只会回应在迭代中使用到的 next 操作。 一旦生成器函数返回退出,迭代终止。我们在迭代中通常使用的for语句会自动处理这些细节,所以你无需担心。

  def frange(start, stop, increment):
    x = start
    while x < stop:
      yield x
      x += increment
  for n in frange(0, 4, 0.5):
    print(n)
  print(list(frange(0, 4, 0.5)))

反向迭代

  a = [1, 2, 3, 4]
  for x in reversed(a):
    print(x, end=' ')

主要想说的是,对象重写__reversed__()方法即可调用reversed()进行反向迭代

itertools的一些使用

  def count(n):
    while True:
      yield n
      n += 1
  c = count(0)
  import itertools
  for x in itertools.islice(c, 10, 20):
    print(x, end=" ")
    
  with open('test.txt') as f:
    for line in f:
      print(line, end='')
  print(format('开始部分的注释不显示', '*>30'))
  with open('test.txt') as f:
    for line in itertools.dropwhile(lambda line: line.startswith('#'), f):
      print(line, end='')
      
  items = ['a', 'b', 'c']
  #items的所有可能组合,不包含相同元素
  for p in itertools.permutations(items):
    print(p, end=' ')
  print()
  #指定长度的所有排序
  for p in itertools.permutations(items, 2):
    print(p, end=' ')

如果遇到一些复杂的迭代器的使用,可以先看看itertools里有没有可用的方法。

同时迭代多个序列

  a = [1, 2, 3]
  b = ['w', 'x', 'y', 'z']
  for i in zip(a,b):
    print(i)
输出:
(1, 'w') (2, 'x') (3, 'y')
for i in itertools.zip_longest(a, b): print(i)
输出:
(1, 'w') (2, 'x') (3, 'y') (None, 'z')

不同序列上的迭代

  import itertools
  a = [1, 2, 3, 4]
  b = ['x', 'y', 'z']
  for x in itertools.chain(a, b):
    print(x)

这样比 a + b 在进行迭代要好很多

展开嵌套的序列

  from collections import Iterable
  def flattern(items, ignore_types=(str, bytes)):
    for x in items:
      if isinstance(x, Iterable) and not isinstance(x, ignore_types):
        yield from flattern(x)
      else:
        yield x
  items = [1, 2, [3, 4, [5, 'hello world'], 7], 8]
  for x in flattern(items):
    print(x, end=' ')

  def count(n):    while True:      yield n      n += 1  c = count(0)  import itertools  for x in itertools.islice(c, 10, 20):    print(x, end=" ")      with open('test.txt') as f:    for line in f:      print(line, end='')  print(format('开始部分的注释不显示', '*>30'))  with open('test.txt') as f:    for line in itertools.dropwhile(lambda line: line.startswith('#'), f):      print(line, end='')        items = ['a', 'b', 'c']  #items的所有可能组合,不包含相同元素  for p in itertools.permutations(items):    print(p, end=' ')  print()  #指定长度的所有排序  for p in itertools.permutations(items, 2):    print(p, end=' ')

原文地址:https://www.cnblogs.com/badboyf/p/6641843.html