Python-イテレーションとイテレーション


>イテレーション

이터레이터(iterator)は、順次値切ることができる객체(object)である.
小作家は時々繰り返し者と呼ばれる.for 반복문과 rangeを使用すると、実際には0から99までのすべての連続数字が生成されるのではなく、値を順次取り出すことができる小さなプログラムが生成される.
連続した数値を事前に作成すると、数値が少なければ少ないほど良いのですが、数値が多すぎるとメモリが必要になり、パフォーマンスにも不利になります.
したがって、Pythonはウィジェットのみを作成し、値が必要な場合に値を作成する方法を使用します.
すなわち,データ生成は後回しであり,これを지연 평가(lazy evaluation)と呼ぶ.

呼び出しウィジェット

>>> it = [1, 2, 3].__iter__()
>>> it.__next__()
1
>>> it.__next__()
2
>>> it.__next__()
3
>>> it.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
__iter__が繰り返し可能なオブジェクトを呼び出すと、ウィジェットがポップアップされ、__next__がウィジェットで呼び出されると、値が順次ポップアップされます.重複可能なオブジェクトがない場合は、StopIterationの例外が発生します.

イテレーションの作成

# 입력
class Counter:
    def __init__(self, stop):
        self.current = 0		# 현재 숫자 유지, 0부터 지정된 숫자 직전까지 반복
        self.stop = stop		# 반복을 끝낼 숫자

    def __iter__(self):
        return self			# 현재 인스턴스를 반환

    def __next__(self):
        if self.current < self.stop:	# 현재 숫자가 반복을 끝낼 숫자보다 작을 때
            r = self.current		# 반환할 숫자를 변수에 자랑
            self.current += 1		# 현재 숫자를 1 증가시킴
            return r			# 숫자를 반환
        else:				# 현재 숫자가 반복을 끝낼 숫자보다 크거나 같을 때
            raise StopIteration		# 예외 발생

for i in Counter(3):
    print(i, end=' ')

# 출력
0 1 2 

ピニオンシール

# 입력
a, b, c = Counter(3)
print(a, b, c)
a, b, c, d, e = Counter(5)
print(a, b, c, d, e)

# 출력
0 1 2
0 1 2 3 4
小型モータは、上記언패킹(unpacking)に達することができる.
もちろん、ウィジェットの繰り返し回数と変数の個数は同じでなければなりません.
よく使われるmap度の小型モータ.したがって、複数の変数に値を割り当てることができます.

>サードパーティ


発電機は小さなモータを生成する関数です.
ジェナレイトは発生器とも呼ばれています.
ウィジェットはクラスで__iter__, __next__ 또는 __getitem__メソッドを実装しなければならないが、ウィジェットは関数にyieldというキーワードを使用するだけでよい.
# 입력
def number_generator():
    yield 0
    yield 1
    yield 2

for i in number_generator():
    print(i)

# 출력
0
1
2
関数にyieldを使用すると、関数はジェネレータとなり、yieldの値(変数)が指定されます.

マネージャの作成

# 입력
def number_generator(stop)
    n = 0			# 숫자는 0부터 시작
    while n < stop:		# 현재 숫자가 반복을 끝낼 숫자보다 작을 때 반복
    	yield n			# 현재 숫자를 바깥으로 전달
        n += 1			# 현재 숫자를 증가시킴

for i in number_generator(3):
    print(i)
    
# 출력
0
1
2
アクセラレータ内に変数nが作成され、0が格納される.
そして、while n < stop:のように、繰り返しが終了した数字よりも小さいときに繰り返します.
繰り返し文では、yield nに数字を渡した後、n1に増やします.
ここではyieldが3回あるので、for 반복문度を3回繰り返します.

降伏から外部に値を複数回渡す


以前はyieldで値を1回外部に伝達していたが、yield fromを用いて値を複数回外部に伝達することができる.
# 입력
def number_generator():
    x = [1, 2, 3]
    yield from x		# 리스트에 들어있는 요소를 한 개씩 밖으로 전달

for i in number_generator():
    print(i)
    
# 출력
1
2
3
一度にyield fromを使用して、値を3回外部に渡します.

はつでんきしき


リスト式を使用する場合は대괄호[]を使用しますが、同じリストを괄호()に組み合わせるとサードパーティ式になります.
リスト式は最初からリスト内の要素を作成しますが、ジェネレータ式は必要に応じて要素を作成するので、メモリを節約できます.
>>> [i for i in range(50) if i % 2 == 0]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]
>>> (i for i in range(50) if i % 2 == 0)
<generator object <genexpr> at 0x7f883061a970>