Подтвердить что ты не робот

Синтаксис Python `for`: код блока против выражений генератора одиночной строки

Я знаком с циклом for в контексте блочного кода. например:

for c in "word":
    print c

Я натолкнулся на некоторые примеры, которые используют for по-разному. Вместо того, чтобы начинать с оператора for, они помечают его в конце выражения (и не включают в себя отложенный код-блок). например:

sum(x*x for x in range(10))

Может ли кто-нибудь указать мне на какую-то документацию, которая описывает это использование for? Я смог найти примеры, но не объяснения. Вся документация for, которую я смог найти, описывает предыдущее использование (пример блочного кода). Я даже не уверен, как назвать это использование, поэтому я приношу свои извинения, если вопрос неясен.

4b9b3361

Ответ 1

То, что вы указываете, - это Generator в Python. Взгляните на: -

См. документацию: - Generator Expression, которая содержит точно такой же пример, который вы опубликовали

Из документации: -

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

Генераторы похожи на List Comprehension, которые вы используете с square brackets вместо brackets, но они более эффективны с точки зрения памяти. Они не возвращают полный результат list в то же время, но возвращают объект-генератор. Всякий раз, когда вы вызываете next() объекта Generator, генератор использует yield для возврата следующего значения.

List Comprehension для вышеуказанного кода будет выглядеть так: -

[x * x for x in range(10)]

Вы также можете добавить условия для фильтрации результатов в конце for.

[x * x for x in range(10) if x % 2 != 0]

Это вернет список numbers, умноженный на 2 в диапазоне от 1 до 5, если число не делится на 2.

Примером Generators, изображающим использование yield, может быть: -

def city_generator():
    yield("Konstanz")
    yield("Zurich")
    yield("Schaffhausen")
    yield("Stuttgart")

>>> x = city_generator()
>>> x.next()
Konstanz
>>> x.next()
Zurich
>>> x.next()
Schaffhausen
>>> x.next()
Stuttgart
>>> x.next()
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
StopIteration

Итак, вы видите, что каждый вызов next() выполняет следующий yield() в Generator. и в конце он бросает StopIteration.

Ответ 2

Это выражения генератора, и они связаны с списком понятий

Сопоставление списков позволяет легко создавать списки. Например, если вы хотите создать список идеальных квадратов, вы можете сделать это:

>>> squares = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Вместо этого вы можете использовать понимание списка:

squares = [x**2 for x in range(10)]

Выражения генератора похожи на списки, за исключением того, что они возвращают объект-генератор вместо списка. Вы можете перебирать этот объект генератора аналогичным образом, чтобы перечислять ошибки, но вам не нужно хранить весь список в памяти сразу, как если бы вы создали список в понимании списка.

Ответ 3

Ваш конкретный пример называется выражением . List comprehensions, словарные понятия и установить понимание имеют сходное значение (разные типы результатов и выражения генератора ленивы) и имеют одинаковый синтаксис, по модулю находящийся внутри других видов скобок, а в случае понимание dict, имеющее expr1: expr2 вместо одного выражения (x * x в вашем примере).