2015-04-25 6 views
1

Я рассмотрел вопрос Difference between function and generator?, но он обозначен как дубликат. Поэтому я размещаю свою версию ответа здесь.Разница между функцией и генератором?

Оригинальный вопрос:

Я ищу для точного различия между нормальной функцией и генератором. Я уже разобрался с ней. Но все результаты довольно сбивают с толку. Я новичок, поэтому я жду короткого и точного примера.

Я пробовал это What is the difference between normal function and generator function?, но не использовал.

Я прошел через это What does the "yield" keyword do in Python?, но его чисто говорящий о генераторе ничего не говорит о различии между функцией и генератором. Мне нужна помощь?

ответ

2

В принципе генераторы являются эффективными с точки зрения памяти для своей ленивой оценки.

A генератор очень похож на функцию, которая возвращает массив, в котором генератор имеет параметры, может быть вызван и генерирует последовательность значений. Однако вместо того, чтобы строить массив, содержащий все значения, и возвращать их все сразу, генератор yields значения по одному, что требует меньше памяти и позволяет вызывающему абоненту немедленно начать обработку первых нескольких значений.

Короче говоря, генератор выглядит как function, но ведет себя как iterator.

from itertools import count 

itertools обеспечивают count генерировать бесконечный поток целого числа. Вы можете дать начало и шаг, чтобы указать начальное и степенное значение для сгенерированного потока. Я собираюсь использовать это в следующем примере.

for i in count(start=0, step=1):  
    print i 

Простой пример для создания списка четных чисел.

Сложение и возвращает список:

def find_even_number_function(number_stream): 
    even_number = [] 
    for n in number_stream: 
     if n % 2 == 0: 
      even_number.append(n) 
    return even_number 

for i in find_even_number_function(count()): 
    print i 

код довольно прост и понятен, но его строит полный список в памяти. Это явно неприемлемо в нашем случае, потому что мы не можем позволить себе хранить все бесконечные целые числа в памяти. Как вы можете видеть, функция никогда не остановится. В этом случае мы будем использовать генератор.

генератор, который yields пункты вместо возврата списка

def find_even_number_generator(number_stream): 
    for n in number_stream: 
     if n % 2 == 0: 
      yield n 

for i in find_even_number_generator(count()): 
    print i 

Следует отметить, что выражение логики формирования числа ясно и естественно. Он очень похож на реализацию, которая построила список в памяти, но имеет характеристику использования памяти для реализации итератора.

Повышение производительности от использования генераторов является результатом ленивого (по требованию) генерации значений, что приводит к снижению использования памяти. Кроме того, нам не нужно ждать, пока все элементы не будут созданы, прежде чем мы начнем их использовать. Это похоже на преимущества, предоставляемые итераторами, но генератор упрощает создание итераторов.

Итак, если вы используете нормальную функцию для вышеуказанного случая, у вас закончится память. Альтернативно, если вы используете функция генератора, у вас не хватит времени.

Смежные вопросы