Tim Peters wrote:
`zip` then creates `n` 2-tuple objects, each of which lives only long enough to be unpacked into `x` and `y`... With "immediate" reclamation of garbage via refcounting, memory use is trival regardless of how large `n` is, as CPython reuses the same heap space over & over & over, ASAP. The space for each 2-tuple is reclaimed before `x-y` is computed...
It's also worth noting that the current refcounting scheme allows for some pretty sneaky optimizations under-the-hood. In your example, `zip` only ever creates one 2-tuple, and keeps reusing it over and over: https://github.com/python/cpython/blob/c96d00e88ead8f99bb6aa1357928ac4545d92... This is thanks to the fact that most `zip` usage looks exactly like yours, where the tuple is only around long enough to be unpacked. If `zip.__next__` knows it's not referenced anywhere else anymore, it is free to mutate(!) it in place. I believe PyUnicode_Append does something similar for string concatenation, as well.