Python 고급 특성의 생 성기
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
at 0x1022ef630>
L 과 g 를 만 드 는 차 이 는 가장 바깥쪽 [] 과 () 에 있 습 니 다. L 은 list 이 고 g 는 generator 입 니 다.우 리 는 list 의 모든 요 소 를 직접 인쇄 할 수 있 지만, generator 의 모든 요 소 를 어떻게 인쇄 합 니까?인쇄 하려 면
next()
함수 로 generator 의 다음 반환 값 을 얻 을 수 있 습 니 다.>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):
File "", line 1, in
StopIteration
우리 가 말 했 듯 이 generator 는 알고리즘 을 저장 하고 호출
next(g)
할 때마다 g 의 다음 요소 의 값 을 계산 합 니 다. 마지막 요소 까지 계산 하고 더 많은 요소 가 없 을 때 StopIteration
의 오 류 를 던 집 니 다.물론 위의 이러한 끊 임 없 는 호출 next(g)
은 너무 변태 적 이다. 정확 한 방법 은 for 순환 이다. 왜냐하면 generator 도 교체 대상 이기 때문이다.>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
...
0
1
4
9
16
25
36
49
64
81
그래서 우 리 는 generator 를 만 든 후에 기본적으로
next()
호출 되 지 않 고 for
순환 을 통 해 교체 되 며 stopIteration
의 오류 에 관심 을 가 질 필요 가 없다.generator 는 매우 강력 합 니 다. 계산 알고리즘 이 가격 보다 복잡 하면 목록 생 성 식 for 순환 이 이 루어 지지 않 을 때 함수 로 도 이 루어 질 수 있 습 니 다.예 를 들 어 유명한 피 폴 라 치 수열 (Fibonacci) 은 첫 번 째 와 두 번 째 수 를 제외 하고 모든 수 를 앞의 두 숫자 에서 더 할 수 있다. 1, 1, 2, 3, 5, 8, 13, 21, 34. 피 폴 라 치 수열 은 목록 생 성 식 으로 쓸 수 없 지만 함수 로 인쇄 하기 쉽다.def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
메모, 할당 문:
a, b = b, a + b
해당:
t = (b, a+ b) #t tuple
a = t[0]
b = t[1]
임시 변수 t 를 쓰 지 않 아 도 값 을 부여 할 수 있 습 니 다.위의 함 수 는 피 보 나치 수열 의 앞 N 개 수 를 출력 할 수 있 습 니 다:
>>> fib(6)
1
1
2
3
5
8
'done'
자세히 살 펴 보면 fib 함 수 는 실제 적 으로 피 보 나치 수열 의 추산 규칙 을 정 의 했 고 첫 번 째 요소 부터 후속 적 으로 임 의적 인 요 소 를 추산 할 수 있다. 이런 논 리 는 사실 generator 와 매우 유사 하 다.즉, 위의 함수 와 generator 는 한 걸음 거리 에 있 습 니 다. fib 함 수 를 generator 로 바 꾸 려 면 print (b) 를 yield b 로 바 꾸 면 됩 니 다.
def fib (max):
n, a, b = 0, 0, 1
while n < max :
yield b
a, b = b, a + b
n = n + 1
return 'done'
이것 이 바로 generator 를 정의 하 는 또 다른 방법 이다.함수 정의 에 yield 키 워드 를 포함 하면 이 함 수 는 일반 함수 가 아니 라 generator 입 니 다.
>>> f = fib(6)
>>> f
여기 서 가장 이해 하기 어 려 운 것 은 generator 와 함수 의 집행 절차 가 다르다 는 것 이다.함 수 는 순서대로 실행 되 며, return 문장 이나 마지막 줄 의 함수 문장 을 만나면 되 돌아 갑 니 다.generator 의 함수 가 되 어 next () 를 호출 할 때마다 실 행 됩 니 다. yield 문 구 를 만 나 다시 실 행 될 때 마지막 으로 돌아 온 yield 문 구 를 계속 실행 합 니 다.간단 한 예 를 들 어 generator 를 정의 하고 숫자 1, 3, 5 를 순서대로 되 돌려 줍 니 다.
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)
이 generator 를 호출 할 때 먼저 generator 대상 을 만 든 다음 next () 함수 로 다음 반환 값 을 계속 얻 습 니 다.
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
File "", line 1, in
StopIteration
이 를 통 해 알 수 있 듯 이 odd 는 일반 함수 가 아니 라 generator 입 니 다. 실행 과정 에서 yield 를 만나면 중단 되 고 다음 에 계속 실행 되 며 3 번 yield 를 실행 한 후에 yield 가 실행 할 수 없 기 때문에 4 번 째 호출 next (o) 가 잘못 되 었 습 니 다.fib 의 예 로 돌아 가면 우 리 는 순환 과정 에서 yield 를 계속 호출 하면 계속 중단 되 고 순환 에 조건 을 설정 하여 순환 을 종료 해 야 합 니 다. 예 를 들 어 무한 수열 이 생 길 수 있 습 니 다.마찬가지 로 함 수 를 generator 로 바 꾼 후에 우 리 는 기본 적 인 뽕나무 는 next () 로 다음 반환 값 을 얻 지 않 고 for 순환 으로 교체 합 니 다.
>>> for n in fib(6):
... print(n)
...
1
1
2
3
5
8
그러나 for 순환 으로 generator 를 호출 할 때 generator 의 return 문장의 반환 값 을 가 져 올 수 없습니다.반환 값 을 받 으 려 면
StopIteration
오 류 를 포착 해 야 합 니 다. 반환 값 은 StopIteration
의 value 에 포함 되 어 있 습 니 다.>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
소결: generator 는 매우 강력 한 도구 입 니 다. Python 에서 목록 생 성 식 을 generator 로 간단하게 바 꿀 수 있 고 함수 로 복잡 한 논 리 를 실현 할 수 있 는 generator 입 니 다.generator 의 작업 원 리 를 이해 하려 면 for 순환 과정 에서 다음 요 소 를 계속 계산 하고 적당 한 조건 에서 for 순환 을 끝 냅 니 다. 함수 가 변 경 된 generator 에 게 return 문 구 를 만 나 거나 함수 체 의 마지막 줄 문 구 를 실행 하 는 것 은 generator 의 명령 을 끝 내 는 것 입 니 다. for 순환 은 이에 따라 끝 납 니 다.일반 함수 와 generator 함 수 를 구분 하 십시오. 일반 함수 호출 은 결 과 를 직접 되 돌려 줍 니 다.
>>> r = abs(6)
>>> r
6
generator 함수 의 "호출" 은 실제 generator 대상 을 되 돌려 줍 니 다:
>>> g = fib(6)
>>> g
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.