[python] 생성기의 제작 방법과 사용 방법
생성기란
생성기는 아무것도 없는 곳에서 균형기를 만드는 것이다.
가장 큰 특징은 실행 지연이다.
이 특징은 무한히 긴 수열을 나타낼 수 있다.
원래 이른바 균형기
컬렉션(리스트와 모듈 등 수치의 집합)에서 요소를 하나하나 추출하는 디자인 모델입니다.
다음은 균형기 사용과 사용하지 않을 때의 for문의 구체적인 예를 살펴보자.
python의 for 문장은 내부에서 균형기를 생성하고 사용합니다.
lst = [0, 1, 2, 3]
# lstからイテレータを生成し、中身を1つずつ取り出している
for i in lst:
print(i)
균형기를 사용하지 않는 for문은python으로 쓸 수 없기 때문에 js의 예입니다.const array = [0, 1, 2, 3]
const n = 4
for (let i = 0; i < array.length; i++) {
// array全体に対して、インデックスでアクセスしている。
console.log(array[i])
}
균형기를 사용할 때 균형기를 통해 모음집에서 값을 하나씩 꺼낸다.다른 한편, 균형기를 사용하지 않으면 색인을 통해 수집 주체에 접근하거나
pop()
등의 방법으로 값을 꺼낼 수 있다.방법·사용법
간단한 예로부터 최종적으로 생성기로 피보나치 수열을 실현한다.
예1: 1, 2, 3의 생성기를 되돌려줍니다
# ジェネレータ関数は普通の関数とは異なるのでそれが分かる命名がよい
def gen_123():
print('egg')
yield 1 # 1回目のnextでここまで実行
print('and')
yield 2 # 2回目のnextでここまで実行
print('spam')
yield 3 # 3回目のnextでここまで実行
print('hum') # 4回目のnextで実行されるが次にyieldがないのでStopIterationを投げる
if __name__ == "__main__":
# ジェネレータ関数からジェネレータを生成
gen = gen_123()
# ジェネレータを1つ目のyieldまで実行
first = next(gen)
# firstには1回目のyieldの値が入る
print(first)
second = next(gen)
print(second)
third = next(gen)
print(third)
fourth = next(gen) # !StopIteration
출력egg
1
and
2
spam
3
hum
Traceback (most recent call last):
File "hoge.py"
fourth = next(gen) # !StopIteration
StopIteration
next(gen)
는 다음yield
까지 진행해 달라는 명령이다.StopIteration은 "
gen
만들어서 생성기를 추진했지만 다음에 돌아올 값이 없다"는 메시지다.참고로 for문은
next(gen)
오른쪽에 쓴 식의 결과로 균형기를 생성하여 StopIteration이 균형기in
에 던져지기 전에 실행하고 수치를 꺼낸다.예2: 1 무한 반환 생성기
def gen_1():
# 無限ループを作成
while True:
# next()されると常に1が返る
yield 1
# 無限ループなので、次のyieldが必ず存在する
# つまり、gen_1()はStopIterationを返さない
if __name__ == "__main__":
count = 0
# gen_1()はStopIterationを返さないので無限ループになる
for i in gen_1():
# 無限ループ防止
if count > 10:
break
print(i)
count += 1
출력1
1
1
1
・
・
・
는 무한 순환과 생성기 함수를 통해 무한 연속의 수열을 나타낼 수 있다.예3: 피보나치 수열
import itertools
def gen_fib():
"""前の値(prev)と今の値(current)を足した値が次の値"""
# 前の値
prev = 1
# 1回目のyieldでは1が取り出される
yield prev
# 今の値
current = 1
# 2回目のyieldも1が取り出される
yield current
# フィボナッチ数列には終わりがないので無限ループ
while True:
# 今の値を(今の値 + 前の値), 前の値を今の値に更新
current, prev = current + prev, current
# 更新された今の値が返る
yield current
if __name__ == "__main__":
# itertools.takewhileを使うことで、
# 無限に続く数列から、条件から外れるまでの値を取り出せる
# 100より小さいフィボナッチ数
print(list(itertools.takewhile(lambda n: n < 100, gen_fib())))
# itertools.isliceを使うことで、
# 無限に続く数列からインデックスで指定した範囲を取り出せる
# 101番目~110番目のフィボナッチ数
print(list(itertools.islice(gen_fib(), 100, 110)))
# itertools.isliceで生成したイテレータに対して、
# 1回だけnextを適応することで、特定のインデックスの値を取り出せる
# 100,001番目のフィボナッチ数は何桁?
print(len(str(
next(itertools.islice(gen_fib(), 100_000, None)))))
출력[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
[573147844013817084101, 927372692193078999176, 1500520536206896083277,
2427893228399975082453, 3928413764606871165730, 6356306993006846248183,
10284720757613717413913, 16641027750620563662096, 26925748508234281076009,
43566776258854844738105] ← 見やすいように改行している
20899
피보나치 수열은 무한히 연장된 수열이다.따라서 next()
라고 쓰면 무한순환에 빠진다.이번 예에서 균형기 구축을 위한 표준 라이브러리
list(gen_fib())
를 사용하여 유한한 균형기를 새로 생성하여 목록을 만들었고 실제로는 수치를 추출했다.최후
생성기로 활약하는 장면으로 무한히 뻗은 피포나치 수열에서 특정 값을 꺼내는 처리를 소개했다.
이걸 일반화하면
itertools
될 거예요.나는 이 글이python에서 프로그래밍을 할 때 생성기를 떠올리는 데 도움을 줄 수 있다고 생각한다.
Reference
이 문제에 관하여([python] 생성기의 제작 방법과 사용 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/shika/articles/2fb64b0a497f385ea5a5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)