On Sun, Apr 15, 2018 at 8:05 AM, Tim Peters <tim.peters@gmail.com> wrote:

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").

Things here remind me of my implementation design for PEP 555: the "contexts" present in the process are represented by a singly-linked tree of assignment objects. It's definitely possible to write the above in a more readable way, and FWIW I don't think it involves "assignments as expressions".
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.

​Why can't the C implementation use Python refcounts? Are you talking about standalone C code? Or perhaps you are thinking about overhead? (In PEP 555 that was not a concern, though). Surely it would make sense to reuse the refcounting code that's already there. There are no cycles here, so it's not particulaly complicated -- just duplication.

Anyway, the whole linked list is unnecessary if the iterable can be iterated over multiple times. But "tee" won't know when to do that. *That* is what I call overhead (unless of course all the tee branches are consumed in an interleaved manner). 

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
Code of Conduct: http://python.org/psf/codeofconduct/

+ Koos Zevenhoven + http://twitter.com/k7hoven +