Использование доходности рекурсивным способом - PullRequest
0 голосов
/ 21 мая 2018

Я играл с yield, и я создал функцию, которая принимает 3 числа и ограничение и вычисляет их особым образом (вычисления не важны, но это видно из кода ниже).

values = []

def compute(limit, a, b, c):
    if a <= limit:
        print("Got {}, {}, {}".format(a, b, c))
        values.append([a, b, c])
        compute(limit, b*c, a*c, a*b)
    else:
        print("Process ended")


compute(9999, 2, 3, 4)
print(values)

Это работает и производит вывод:

Got 2, 3, 4
Got 12, 8, 6
Got 48, 72, 96
Got 6912, 4608, 3456
Process ended
[[2, 3, 4], [12, 8, 6], [48, 72, 96], [6912, 4608, 3456]]

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

Причина, по которой я вообще беспокоюсь, заключается просто в том, почему yield используется в первую очередь - здесь это не имеет значения, но что, если моей задаче потребовалось 100000-е значение из этого списка - не нужно создавать его целиком или даже просто глупо, учитывая, что я не хочу предыдущих значений 99999 ...

Я пытался использовать что-тонапример:

def compute_y(a, b, c):
    while True:
        yield b*c, a*c, b*a

for a, b, c in compute_y(2, 3, 4):
    if a > 9999:
        break

Проблема в том, что числа в for всегда одинаковы (2, 3 и 4), поэтому никогда не достигнут других значений, и поэтомубесконечный цикл.

tl; dr - можно ли вообще использовать yield здесь, чтобы сделать алгоритм более эффективным для больших списков?

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Хорошо, вся проблема была вызвана тем, что я подумал, что yield работает аналогично return, не заботясь о последних строках после yield.

Все это с использованием yield (сподсказка Ry- ) работает следующим образом:

def compute_y(a, b, c):
    while True:
        yield a, b, c
        a, b, c = b*c, a*c, b*a


for a, b, c in compute_y(2, 3, 4):
    if a < 9999:
        print(a, b, c)
    else:
        break

Вывод:

2 3 4
12 8 6
48 72 96
6912 4608 3456
0 голосов
/ 21 мая 2018

Да, вам нужно будет присвоить новые значения для следующей итерации цикла:

def compute_y(a, b, c):
    while True:
        yield a, b, c
        a, b, c = b*c, a*c, b*a
...