산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> python

파이썬 생성기

파이썬 생성기

이 자습서에서는 Python 생성기를 사용하여 반복을 쉽게 생성하는 방법, 반복기 및 일반 함수와 어떻게 다른지, 사용해야 하는 이유를 배웁니다.

동영상:Python 생성기

파이썬의 생성기

파이썬에서 반복자를 만드는 데는 많은 작업이 있습니다. __iter__() 클래스를 구현해야 합니다. 및 __next__() 메서드, 내부 상태를 추적하고 StopIteration 올리기 반환할 값이 없을 때.

이것은 길고 직관적이지 않습니다. 그런 상황에서 제너레이터가 구해줍니다.

Python 생성기는 반복자를 만드는 간단한 방법입니다. 위에서 언급한 모든 작업은 Python의 생성기에 의해 자동으로 처리됩니다.

간단히 말해서, 제너레이터는 한 번에 하나의 값을 반복할 수 있는 객체(반복자)를 반환하는 함수입니다.

<시간>

Python에서 생성기 만들기

Python에서 생성기를 만드는 것은 매우 간단합니다. 일반 함수를 정의하는 것만큼 쉽지만 yield return 대신 문 성명서.

함수에 yield가 하나 이상 포함된 경우 문(다른 yield를 포함할 수 있음 또는 return 문), 제너레이터 함수가 됩니다. yield 둘 다 및 return 함수에서 일부 값을 반환합니다.

차이점은 return 문은 함수를 완전히 종료합니다. yield 문은 모든 상태를 저장하는 함수를 일시 중지하고 나중에 연속적인 호출에서 거기에서 계속합니다.

<시간>

제너레이터 기능과 일반 기능의 차이점

다음은 제너레이터 함수가 일반 함수와 어떻게 다른지 보여줍니다.

다음은 위에서 언급한 모든 요점을 설명하는 예입니다. my_gen()이라는 생성기 함수가 있습니다. 여러 yield 진술.

# A simple generator function
def my_gen():
    n = 1
    print('This is printed first')
    # Generator function contains yield statements
    yield n

    n += 1
    print('This is printed second')
    yield n

    n += 1
    print('This is printed at last')
    yield n

인터프리터의 대화식 실행은 아래에 나와 있습니다. 출력을 보려면 Python 셸에서 실행하십시오.

>>> # It returns an object but does not start execution immediately.
>>> a = my_gen()

>>> # We can iterate through the items using next().
>>> next(a)
This is printed first
1
>>> # Once the function yields, the function is paused and the control is transferred to the caller.

>>> # Local variables and theirs states are remembered between successive calls.
>>> next(a)
This is printed second
2

>>> next(a)
This is printed at last
3

>>> # Finally, when the function terminates, StopIteration is raised automatically on further calls.
>>> next(a)
Traceback (most recent call last):
...
StopIteration
>>> next(a)
Traceback (most recent call last):
...
StopIteration

위의 예에서 주목해야 할 한 가지 흥미로운 점은 변수 n의 값이 각 호출 사이에 기억됩니다.

일반 함수와 달리 지역 변수는 함수가 양보할 때 소멸되지 않습니다. 또한 생성기 개체는 한 번만 반복할 수 있습니다.

프로세스를 다시 시작하려면 a = my_gen()과 같은 것을 사용하여 다른 생성기 객체를 생성해야 합니다. .

마지막으로 주의할 점은 for 루프와 함께 생성기를 직접 사용할 수 있다는 것입니다.

이는 for 때문입니다. 루프는 반복자를 취하고 next()를 사용하여 반복합니다. 기능. StopIteration일 때 자동으로 종료됩니다. 제기된다. Python에서 for 루프가 실제로 어떻게 구현되는지 알아보려면 여기를 확인하세요.

# A simple generator function
def my_gen():
    n = 1
    print('This is printed first')
    # Generator function contains yield statements
    yield n

    n += 1
    print('This is printed second')
    yield n

    n += 1
    print('This is printed at last')
    yield n


# Using for loop
for item in my_gen():
    print(item)

프로그램을 실행하면 다음과 같이 출력됩니다.

This is printed first
1
This is printed second
2
This is printed at last
3
<시간>

루프가 있는 Python 생성기

위의 예는 덜 사용되며 배경에서 무슨 일이 일어나고 있는지 알아보기 위해 연구했습니다.

일반적으로 제너레이터 기능은 적절한 종료 조건을 갖는 루프로 구현됩니다.

문자열을 반전시키는 생성기의 예를 들어보겠습니다.

def rev_str(my_str):
    length = len(my_str)
    for i in range(length - 1, -1, -1):
        yield my_str[i]


# For loop to reverse the string
for char in rev_str("hello"):
    print(char)

출력

o
l
l
e
h

이 예에서는 range()를 사용했습니다. for 루프를 사용하여 역순으로 인덱스를 가져오는 함수입니다.

참고 :이 생성기 함수는 문자열뿐만 아니라 목록, 튜플 등과 같은 다른 종류의 이터러블에서도 작동합니다.

<시간>

파이썬 생성기 표현식

간단한 생성기는 생성기 표현식을 사용하여 즉석에서 쉽게 생성할 수 있습니다. 발전기를 쉽게 만들 수 있습니다.

익명 함수를 생성하는 람다 함수와 유사하게, 생성기 표현식은 익명 생성기 함수를 생성합니다.

생성기 표현식의 구문은 Python의 목록 이해와 유사합니다. 그러나 대괄호는 둥근 괄호로 대체됩니다.

목록 이해와 생성기 표현식의 주요 차이점은 목록 이해가 전체 목록을 생성하는 반면 생성기 표현식은 한 번에 하나의 항목을 생성한다는 것입니다.

그들은 게으른 실행을 가지고 있습니다(요청할 때만 항목을 생성함). 이러한 이유로 제너레이터 표현식은 동등한 목록 이해보다 훨씬 더 메모리 효율적입니다.

# Initialize the list
my_list = [1, 3, 6, 10]

# square each term using list comprehension
list_ = [x**2 for x in my_list]

# same thing can be done using a generator expression
# generator expressions are surrounded by parenthesis ()
generator = (x**2 for x in my_list)

print(list_)
print(generator)

출력

[1, 9, 36, 100]
<generator object <genexpr> at 0x7f5d4eb4bf50>

위에서 제너레이터 표현식이 필요한 결과를 즉시 생성하지 않았음을 알 수 있습니다. 대신 요청 시에만 항목을 생성하는 생성기 개체를 반환했습니다.

생성기에서 항목을 가져오는 방법은 다음과 같습니다.

# Initialize the list
my_list = [1, 3, 6, 10]

a = (x**2 for x in my_list)
print(next(a))

print(next(a))

print(next(a))

print(next(a))

next(a)

위의 프로그램을 실행하면 다음과 같은 결과가 나옵니다.

1
9
36
100
Traceback (most recent call last):
  File "<string>", line 15, in <module>
StopIteration

생성기 표현식을 함수 인수로 사용할 수 있습니다. 이런 식으로 사용하면 둥근 괄호를 뺄 수 있습니다.

>>> sum(x**2 for x in my_list)
146

>>> max(x**2 for x in my_list)
100
<시간>

Python 생성기 사용

제너레이터를 강력한 구현으로 만드는 데에는 몇 가지 이유가 있습니다.

1. 구현하기 쉬움

Generator는 Iterator 클래스에 비해 명확하고 간결한 방식으로 구현될 수 있습니다. 다음은 반복자 클래스를 사용하여 2의 거듭제곱 수열을 구현하는 예입니다.

class PowTwo:
    def __init__(self, max=0):
        self.n = 0
        self.max = max

    def __iter__(self):
        return self

    def __next__(self):
        if self.n > self.max:
            raise StopIteration

        result = 2 ** self.n
        self.n += 1
        return result

위의 프로그램은 길고 혼란스러웠습니다. 이제 생성기 함수를 사용하여 동일한 작업을 수행해 보겠습니다.

def PowTwoGen(max=0):
    n = 0
    while n < max:
        yield 2 ** n
        n += 1

생성기는 세부 정보를 자동으로 추적하므로 구현이 간결하고 훨씬 깔끔해졌습니다.

2. 메모리 효율성

시퀀스를 반환하는 일반 함수는 결과를 반환하기 전에 메모리에 전체 시퀀스를 생성합니다. 시퀀스의 항목 수가 매우 많으면 이는 과잉입니다.

이러한 시퀀스의 생성기 구현은 메모리 친화적이며 한 번에 하나의 항목만 생성하므로 선호됩니다.

3. 무한 스트림을 나타냅니다.

생성기는 데이터의 무한한 흐름을 나타내는 훌륭한 매체입니다. 무한 스트림은 메모리에 저장할 수 없으며 생성기는 한 번에 하나의 항목만 생성하므로 데이터의 무한 스트림을 나타낼 수 있습니다.

다음 생성기 함수는 (적어도 이론상) 모든 짝수를 생성할 수 있습니다.

def all_even():
    n = 0
    while True:
        yield n
        n += 2

4. 파이프라이닝 생성기

여러 생성기를 사용하여 일련의 작업을 파이프라인할 수 있습니다. 이것은 예를 사용하여 가장 잘 설명됩니다.

피보나치 수열의 숫자를 생성하는 생성기가 있다고 가정합니다. 그리고 숫자 제곱을 위한 또 다른 생성기가 있습니다.

피보나치 급수에서 숫자의 제곱의 합을 찾으려면 생성기 함수의 출력을 함께 파이프라인하여 다음과 같이 할 수 있습니다.

def fibonacci_numbers(nums):
    x, y = 0, 1
    for _ in range(nums):
        x, y = y, x+y
        yield x

def square(nums):
    for num in nums:
        yield num**2

print(sum(square(fibonacci_numbers(10))))

출력

4895

이 파이프라이닝은 효율적이고 읽기 쉽습니다(예, 훨씬 시원합니다!).


python

  1. 파이썬 연산자
  2. 파이썬 함수 인수
  3. 파이썬 사전
  4. 파이썬 생성기
  5. 파이썬 클로저
  6. 파이썬 데코레이터
  7. 예제가 있는 Python Lambda 함수
  8. Python abs() 함수:절대값 예제
  9. 예제가 있는 Python round() 함수
  10. 예제가 있는 Python map() 함수