Как генераторы Python экономят память и время? - PullRequest
0 голосов
/ 04 марта 2020

Я работаю над генераторами. Я не могу легко взять некоторые данные, которые я узнал.

y = []
def x(a: int) -> None:
    for x in range(a):
        y.append(x)

def z(a):
    for i in range(a):
        yield i

x(10**6)
t = z(10**6)
print(next(t))
print(next(t))

Сравнивая два кода,

первый код;

  • y создает объект списка, устанавливая []
  • И для l oop функция y.append () вызывает 10 ** 6 раз и выполняет операции
  • Если я хочу достичь какого-либо значения y, y будет go для кучи памяти и извлечения данных, которые я только что запросил

второй код;

Все значения будут возвращены, когда я вызову t = z (10 ** 6)? или он выдаст, когда я вызываю следующую функцию, я имею в виду, когда я использую следующую функцию, он будет go генератором и выдаст следующее значение и получит его оттуда? Помнит ли он, где он оставил указатель? Удаляет ли оно значение после следующей используемой функции, то есть после вызова print (next (t)), оно будет удалено сразу после операции? Заранее спасибо!

1 Ответ

0 голосов
/ 04 марта 2020

Я предполагаю CPython здесь.

В примере 1 y поддерживается структурой C ListObject, выделенной в куче, которая (с некоторыми атрибутами) length целое число и массив Object* указателей.

Несмотря на проверку ошибок, что-то вроде y[1234] заканчивается аналогом y->entries[1234].

В примере 2 вызов функция генератора выделяет генератор, который содержит состояние функции генератора.

Вызов next() для генератора будет запускать код функции генератора до следующего yield. В этот момент состояние функции (и далее, range(), которая также является генератором), состояние сохраняется, и значение возвращается через next() вызывающей стороне. Для генератора сами значения не сохраняются (если вы, например, не изменяете массив).

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...