@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.