Iterable、I歪み、ジェネレータ


Pythonを少し勉強すれば、出会ったiterableiteratorgeneratorを整理したいと思います.明らかに、以前も小さなラベル、小さなラベル、発電機を勉強したことがありますが、見るたびに理解しにくいです.だから、本文では、なぜ書くのか、どこに書くのかなどを明確に定義します.

Iterable

__iter__メソッドを実装したオブジェクトをインタラクティブオブジェクトと呼ぶ.簡単に言えば、繰り返し可能なオブジェクトを指します.ここでいう繰り返しとは、一度に1つの要素をもたらすことを意味します.すなわち、iterableオブジェクトは一度に1つの要素しか取得できません.
では、オブジェクトの要素iterableを繰り返しインポートするにはどうすればいいのでしょうか.iteratorをそのまま使用すればよい.

Iterator

iterableオブジェクトへの呼び出しiter()関数はiteratorになります.iteratorに設定すると、next()または__next__メソッドを使用して、次の要素にアクセスできます.すべての要素が返されると、stopIterationエラーが発生します.
また、iterableオブジェクトをiteratorに置き換えず、組み込み関数next()を使用すると、そのオブジェクトがiteratorではないというエラーが発生します.iteratorすべての操作が完了したら、結果を一度にメモリにロードします.for文を使用する場合はiterableオブジェクトが使用されます.なぜなら、for文の内部でiterableオブジェクトがiteratorオブジェクトとして作成されるからです.すなわち、以下のfor文を実行すると、iter(obj)生成iteratorが自動的に実行される.
< for 문의 내부 코드 >
# create an iterator object from that iterable
iter_obj = iter(iterable)

# infinite loop
while True:
    try:
        # get the next item
        element = next(iter_obj)
        # do something with element
    except StopIteration:
        # if StopIteration is raised, break from loop
        break

どのオブジェクトがIterableですか?

for要素iterableオブジェクトを文で返すことができる場合.より正確には、対象内部メソッドが__iter__であれば、iterableである.また、ここで__next__メソッドが存在する場合はiteratorである.
test = 'abcdefg'
print(dir(test))
# ['__add__', '__class__', '__dir__', '__doc__', '__iter__', .....]
print(dir(iter(test)))
# [ '__iter__', '__le__', '__ne__', '__new__', '__next__', ...]
dirを使用して、オブジェクトの内部にどのような方法があるかを決定します.

なぜ奇胎器を使うのか


オブジェクトに複数の要素値がある場合、これらの要素に順次アクセスできます.すなわち、イテレーションがない場合、listなどのアレイ内の各要素にアクセスできません.

generator


ここです。においてもまとめられているが、jner layerは特殊なiteratorであると再定義される.つまり、すべての発電機は小さなモータです.しかし、前のウィジェットの特徴__iter____next__の方法を使用することを避け、yieldを使用してより簡潔でPythonスタイルの文法を提供します.
発電機を生成する方法はリスト計算に似ている.[]()に変換するだけです.
サードパーティを使い捨て関数として使用すると、再呼び出し後に結果は返されません.
def fuc():
  yield "hi"
  yield "I AM generator"
  yield "generator is iterator"
  yield "but iterator is not generator"

generator = fuc()
print(generator)	# <generator object fuc at 0x7fed65d78f90>
print(next(generator))	# hi

for i in generator:
  print("first", i)	# I AM generator/generator is iterator/but iterator is not generator

for i in generator:
  print("second", i)	# 결과 반환 X

ジェネレータを使用する理由

  • iteratorの中の__next__,__iter__は優雅で簡潔な手書きの方法である
  • 必要に応じて、その時点で値を生成することができ、メモリ容量の節約に役立ちます.
  • import sys
    print(sys.getsizeof([i for i in range(1000)]))	# iterator : 9016
    print(sys.getsizeof((i for i in range(1000))))	# generator : 112
    上記のコードから、ウィジェットに比べて、ウィジェットのメモリ効率がどれほど高いかがわかります.

    generatorを使用した逆()関数の実装

    def make_reversed(a:list):
      for i in range(len(a)):
        yield a[-i-1]
        
    generator = make_reversed([1,2,3,4,5])	
    print(generator)	# <generator object make_reversed at 0x7f94ec765f90>
    
    for j in generator:
      print(j)		# 5,4,3,2,1
    reverseは、新しいリストではなく、インデックス値を使用して元のリストを返すため、メモリを無駄にしません.