# Write an infinitely nested generator comprehension

The goal is to create a generator generator [...] generator generator comprehension.

1. The generator must be created via generator comprehension.
2. The following expression must be valid for any number of nestings: next(next(next(next(next(generator))))).

The winner is whoever achieves this with the fewest number of bytes.

# Python, 31 26 25 bytes

x=(x for()in iter(set,1))

Attempt This Online!

If assignment is not allowed:

# Python, 77 72 71 bytes

(gc.get_referrers(sys._getframe())[0]for()in iter(set,1))
import gc,sys

Attempt This Online!

(this is bad code)

-5 bytes on both solutions thanks to @ovs

• Wow, very cool! Thanks for demoing this, I have been trying to figure it out for a while now. Oct 31, 2021 at 8:03
• You can save a couple bytes by using a builtin function instead of the lambda, e.g. iter(int,1)
– ovs
Oct 31, 2021 at 8:44

@pxeger's solution is pretty much the end of this challenge. A generator expression must include code like (a for b in c), where a must be a generator which behaves like the outer generator expression behaves. Either a refers to the outer generator itself, or a is a shorter solution to this problem; so a shortest solution must look like x=(x for b in c). For this to be a solution, then c must be an infinite iterator.

I don't have a proof that iter(int,1) is the shortest possible way to make an infinite iterator, but it seems unbeatable. Otherwise, the only way to improve on @pxeger's solution is if you can write an infinite iterator in fewer than 11 bytes.

If we relax the rule requiring the result to be created using a generator expression, then here's a few other ideas:

Using iter: (18 bytes)

x=iter(lambda:x,1)


Using yield: (23 bytes)

def f():yield f()
x=f()


Using itertools.cycle: (44 bytes)

import itertools as i
x=i.cycle(l:=[])
l+=x,


That said, if the rule is only that the outer-most generator be created using a generator expression, and the results after that need not be generators (just things that next works on, i.e. any iterators), then a in the code above can be some solution to the relaxed challenge, instead of a self-reference: (32 bytes)

(z:=iter(lambda:z,1)for _ in[1])


This method still can't beat @pxeger's solution, unless there is a solution to the relaxed version of the challenge more than 6 bytes shorter than z:=iter(lambda:z,1). This seems pretty unlikely, and even if it is possible, it would presumably be an infinite iterator; so it would still be shorter if you plugged it into @pxeger's solution instead of this one.

• I thought iter created an iterator, not a generator, are they the same thing? Also, I think the challenge requires using a generator comprehension.
– user
Oct 31, 2021 at 20:34
• @user "If we relax the rule requiring the result to be created using a generator expression" Oct 31, 2021 at 20:35
• I missed that, sorry. I think you do also need a main answer that does comply with the challenge, though.
– user
Oct 31, 2021 at 20:36
• @user I don't believe it is possible to write a good solution which is substantially different to pxeger's solution, as I explained in the first half of my answer. Either the a part of the generator expression refers to the generator expression itself, in which case you get a version of their solution, or it does not, in which case the a part is a shorter solution to the problem. Oct 31, 2021 at 20:39
• @pxeger Interesting idea, best I can do is l=[];l+=l,;x=(x for l[1:]in l) for 30 bytes. The alternative is l=[1];x=(l.append(1)or x for _ in l) for 36 bytes. The slice assignment is shorter than writing append but it only works if l contains copies of itself, which requires more setup. Nov 1, 2021 at 23:02