Вы неправильно поняли цикл for. Используется для повторения определенных действий, пока указанное условие не станет ложным. Ваше условие - это задание, поэтому есть ошибка.
Поэтому измените это
для ($ i = 0; $ row = $ result-> fetch (); $ i ++) {
blockquote>на следующее:
foreach ($result->fetch_all() as $row) {
$ result-> fetch_all () возвращает ассоциативный массив данных. С помощью цикла foreach вы получаете доступ к каждому элементу в этом массиве и можете получить к нему доступ с помощью $ row ['any-key-you-want']
Другой вариант - использовать функцию itertools.tee ()
для создания второй версии вашего генератора:
y = FunctionWithYield()
y, y_backup = tee(y)
for x in y:
print(x)
for x in y_backup:
print(x)
Это может быть полезно с точки зрения использования памяти если исходная итерация могла обработать не все элементы.
Можно сделать это при помощи itertools.cycle () , можно создать итератор с этим методом и затем выполниться для цикла по итератору, который циклично выполнится по его значениям.
, Например:
def generator():
for j in cycle([i for i in range(5)]):
yield j
gen = generator()
for i in range(20):
print(next(gen))
генерирует 20 чисел, от 0 до 4 неоднократно.
А отмечают в документах:
Note, this member of the toolkit may require significant auxiliary storage (depending on the length of the iterable).
Если ответа Гжегожа Оледски недостаточно, вы, вероятно, могли бы использовать send ()
для достижения своей цели. См. PEP-0342 для получения дополнительных сведений об улучшенных генераторах и выражениях yield.
ОБНОВЛЕНИЕ: См. Также itertools.tee ()
. Это связано с некоторыми из упомянутых выше компромиссов между памятью и обработкой, но может сэкономить некоторую память вместо простого сохранения результатов генератора в списке
; это зависит от того, как вы используете генератор.
Вероятно, самое простое решение - обернуть дорогую часть в объект и передать ее генератору:
data = ExpensiveSetup()
for x in FunctionWithYield(data): pass
for x in FunctionWithYield(data): pass
Таким образом, вы можете кэшировать дорогостоящие вычисления.
Если вы можете сохранять все результаты в ОЗУ одновременно, затем использовать list ()
, чтобы материализовать результаты генератора в виде простого списка и работать с ним.
Генераторы не могут быть перемотаны. У вас есть следующие варианты:
Снова запустить функцию генератора, перезапустив генерацию:
y = FunctionWithYield ()
для x в y: print (x)
y = FunctionWithYield ()
для x в y: print (x)
Сохраните результаты генератора в структуре данных в памяти или на диске, которую можно повторять снова:
y = list (FunctionWithYield ())
для x в y: print (x)
# можно повторить снова:
для x в y: print (x)
Обратной стороной варианта 1 является повторное вычисление значений. Если это загружает процессор, вам придется рассчитывать дважды. С другой стороны, обратная сторона 2 - это хранилище. Весь список значений будет сохранен в памяти. Если имеется слишком много значений, это может быть непрактичным.
Итак, у вас есть классический компромисс между памятью и обработкой . Я не могу представить себе способ перемотки генератора без сохранения значений или их повторного вычисления.
Я не уверен, что вы имели в виду под дорогой подготовкой, но я думаю, что у вас действительно есть
data = ... # Expensive computation
y = FunctionWithYield(data)
for x in y: print(x)
#here must be something to reset 'y'
# this is expensive - data = ... # Expensive computation
# y = FunctionWithYield(data)
for x in y: print(x)
Если это случае, почему бы не использовать повторно данные
?