Then I thought "this is stupid! Python already does reference
counting." Voila! Vast swaths of tedious code vanished, giving this
remarkably simple implementation:
def mytee(xs, n):
last = [None, None]
def gen(it, mylast):
nonlocal last
while True:
mylast = mylast[1]
if not mylast:
mylast = last[1] = last = [next(it), None]
yield mylast[0]
it = iter(xs)
return tuple(gen(it, last) for _ in range(n))
There's no need to keep a pointer to the start of the shared list at
all - we only need a pointer to the end of the list ("last"), and each
derived generator only needs a pointer to its own current position in
the list ("mylast").
What I find kind of hilarious is that it's no help at all as a
prototype for a C implementation: Python recycles stale `[next(it),
None]` pairs all by itself, when their internal refcounts fall to 0.
That's the hardest part.
BTW, I certainly don't suggest adding this to the itertools docs
either. While it's short and elegant, it's too subtle to grasp easily
- if you think "it's obvious", you haven't yet thought hard enough
about the problem ;-)
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/