PythonでのIterator反復器の使用雑談

5217 ワード

反復器はnext()操作をサポートするオブジェクトです.next()操作を実行すると、要素のセットが含まれます.すべての要素が戻されると、StopIteration例外が生成されます.

>>>a=[1,2,3]
>>>ia=iter(a)
>>>next(ia)
1
>>>next(ia)
2
>>>next(ia)
3
>>>next(ia)
Traceback (most recent call last):
 File "", line 1, in 
StopIteration

ite()は、list、tuple、dict、setなど、複数のPythonオブジェクトをパラメータとして受け入れ、反復器に変換することができる.反復器はfor文またはin文で使用できます.多くの一般的な操作も、sum()、max()などの反復器をサポートしています.

>>> b=[4,5,6]
>>> ib=iter(b)
>>> for x in ib:
...   print(x)
...
4
5
6
>>> ic=iter(b)
>>> sum(ic)
15
>>> id=iter(b)
>>> max(ic)
6


反復器には多くのメリットがあります.
1.「ストリーミング」データ処理方式はメモリの消耗を減らす:例えばファイルを処理して、急にすべてのデータを取り出してメモリの中に入れて処理すると、プログラムが大量のメモリを消耗することができて、時にはできないこともあって、普通私達は一部のファイルの内容に対して処理を行う:

for text_line in open("xx.txt"):
 print text_line

2.またはxmlファイルを処理する場合:

tree = etree.iterparse(xml, ['start', 'end'])
for event, elem in tree:
  if event == "end"
    result = etree.tostring(elem)
    elem.clear()
    print result

内蔵関数openが返すfileオブジェクトとetree.iterparseシーケンス化xml treeは反復可能なオブジェクトであり、ファイルの内容を漸進的に処理することができます.
3.for文でデータの消費を容易にすることをサポートします:python内蔵のいくつかのよく見られるタイプは配列、リスト、文字列などが反復可能なタイプで、このように私たちはfor文という文法糖がデータの消費を便利にすることができて、自分でインデックスの位置を記録する必要がなくて、人肉の循環:

for i in [1, 2, 3, 4]
 print i,

反復器の利点を簡単に理解した後、pythonの反復器モードについて話しています.ここでは,反復可能オブジェクトと反復器オブジェクトの2つの比較的迂回的な名詞を導入し,個人的にはこの2つの概念から反復器をよりよく理解すると考えられる.例を置く前に、この2つの概念に対して1つの流入しない解釈を与えます.
反復可能オブジェクト:オブジェクトに__が含まれています.iter()__メソッドの実装では、オブジェクトのiter関数が呼び出されると、特定のデータ取得の実装を含む反復器が返されます.反復器:nextメソッドの実装を含み,所望のデータを正確な範囲で返し,範囲を超えた後にStopIterationのエラーを投げ出して反復を停止できる.例を挙げて見ながら言います.

class iterable_range:
  def __init__(self, n):
    self.n = n

  def __iter__(self):
    return my_range_iterator(self.n)

class my_range_iterator:
  def __init__(self, n):
    self.i = 0
    self.n = n

  def next(self):
    if self.i < self.n:
      i = self.i
      self.i += 1
      print 'iterator get number:', i
      return i
    else:
      raise StopIteration()


例のiterable_rangeは反復可能なオブジェクトなので、for文で反復することもできます.

temp = my_range(10)
for item in temp:
  print item,


出力:

  my iterator get number: 0
  0
  my iterator get number: 1
  1
  my iterator get number: 2
  2
  my iterator get number: 3
  3
  my iterator get number: 4
  4
  my iterator get number: 5
  5
  my iterator get number: 6
  6
  my iterator get number: 7
  7
  my iterator get number: 8
  8
  my iterator get number: 9
  9

出力されたログをよく見てみましょう.
  • データは確かに「フロー」処理の
  • である.
  • iteratorは本当に背後で仕事をしている人
  • です.
  • for文は、オブジェクトのデータを反復するのに非常に便利です.

  • 反復可能なオブジェクトは、実際には反復モードモード全体の上位レベルに似ています.契約の規範のように、実際の作業で作業している反復器オブジェクトに戻ることを保証します.for,sumなど反復可能なオブジェクトを受け入れる方法は,呼び出しオブジェクトの__に従う.iter__を選択します.forを例に挙げます.
    
    iterator_object = iterable_object.__iter__()
    while True:
      try:
        value = iterator_object.next()
      except StopIteration:
        # StopIteration exception is raised after last element
        break
    
      # loop code
      print value
    
    

    forという構文糖の背後にある論理差は、上記の例のコードで示されているように、まず反復可能なオブジェクトが返す反復器オブジェクトを取得し、次に反復器オブジェクトのnextメソッドを呼び出して各値を取得し、値を取得する過程で境界を随時検出します.つまり、StopIterationのようなエラーが投げ出されたかどうかをチェックします.反復オブジェクトがエラーを投げ出すと反復が停止する(note:この例から分かるように、反復可能なオブジェクトを受け入れる方法について、単純な反復オブジェクトを渡すのも実際には動作しない場合、TypeError:iteration over non-sequenceのようなエラーが報告される可能性があります).もちろん、一般的にはアプリケーション中にわざわざ分離することはありません.反復オブジェクトを少し修正して、_を追加することができます.iter__メソッドの実装により、オブジェクト自体が反復可能なオブジェクトであり、反復可能なオブジェクトでもあります.
    
    class my_range_iterator:
       def __init__(self, n):
        self.i = 0
        self.n = n
    
       def __iter__(self):
        return self
    
       def next(self):
        if self.i < self.n:
          i = self.i
    
          self.i += 1
          print 'my iterator get number:', i
          return i
        else:
          raise StopIteration()
    
     for item in my_range_iterator(10):
       print item
    
    

    出力:
     
    
      my iterator get number: 0
      0
      my iterator get number: 1
      1
      my iterator get number: 2
      2
      my iterator get number: 3
      3
      my iterator get number: 4
      4
      my iterator get number: 5
      5
      my iterator get number: 6
      6
      my iterator get number: 7
      7
      my iterator get number: 8
      8
      my iterator get number: 9
      9