Grabbing Variables from Generator Functions

I have some code for infinity many values here:

def j ():
k=0
while True:
k+=1
yield k

which doesn’t seem to run forever

but when attached to a loop:

for k in j():
#do stuff

it gets stack overflow

is there a way to use the former without running the loop indefinitely?
maybe some way to calculate it all at once?

Can you show an example of the “do stuff”? When I run your code with a simple print(k), or even a pass, it loops as long as I care to wait and does not generate an overflow.

Can you give a runnable code of something that shows the overflow? (and please put the code inside triple backtick lines so the formatting is preserved)

No error for me version:

def j ():
    k=0
    while True:
        k+=1
        yield k


for x in j():
    pass

in your code you used x in the for loop
was this intentional?

It was intentional in that Heat Jack had to use some name for the loop
variable, the name doesn’t matter one whit, and “x” is as good a name as
any.

The variable used for the loop has absolutely no connection to the name
used inside the generator. It is like when I write a function:

def calc_something(a, b, c):
    d = a + b - c
    e = 2*d
    return e

and then call the function:

x = calc_something(10, 2, 5)
print(x)
# prints 14

the parameters and variables used inside the function (a, b, c, d, e)
are not connected to the variable that I use outside the function to
collect the result (x).

Oops, my apologies, I mixed up Heat Jack and BowlOfRed.

Sorry about that BowlOfRed.

Your generator will run forever. And it doesn’t cause a stack overflow.
What makes you think it does?

It is impossible for you to “calculate it all at once”, that would
require an infinite number of values to be calculated. Since the
universe itself is finite, where would you put them all?

In practice, Python lists are not capable of being actually infinite,
they have a very large but finite hard limit to the number of values
they can hold:

which on my computer is 9223372036854775807. That is the theoretical
upper limit to how many items you could store in a single list. By my
calculation, my computer would take more than 2340 years to calculate
that number of values.

Of course in reality your computer would run out of memory long before
that happened: if you had 64GB of memory in your PC (a million times
what Bill Gates said that nobody would ever need more than), there is a
hard limit of a mere 8589934592 8-byte pointers, less whatever memory is
being used by the interpreter, the operating system, other programs, and
the objects that the pointers point to.

But that’s getting stuck in the gory details of memory on a PC. In
practical terms, although the generator will (theoretically) run
forever, in practice your computer will run out of memory after mere
billions of values are calculated.

So no, of course you cannot generate all the values of an infinite loop
at once.

Can you be a bit more detailed in what precisely you are trying to do?

You have a generator that will run forever, or at least until the sun
funs out of hydrogen in a few billion years, expands and destroys the
earth. If you run it in a loop, you can process each item one at a time.
You can’t compute the not-actually-infinite-merely-humongous number of
values all at once and collect them into a list.

So in practical terms, what would you like to do? Can you give an
example of what sort of result you expect? Something a bit smaller than
a bazillion-bazillion-bazillion-bazillion values?

No it wasn’t intentional. I cut & pasted the first part and typed the second without noticing the variable. Changing it back to k makes no difference though. It still does not produce a stack overflow.

I have a generator to make an infinite list of numbers


 t = 0 
u = []
def h ():
 while True:
  t = t + 1
  u.append(t)
  yield u
h ()

But how do I use it?


 z = any(u)


def func():
  func.variable = "John"

func()

print(func.variable)

This works

But it’s with a regular function not a generator

Function h() generates only UnboundLocalError as t is referenced before assignment.

Python has built-in iterator of infinite stream of numbers: itertools.count() so why not take advantage of ‘battaries included’ feature of Python.

2 Likes