I'm trying to iterate over 3 elements at a time using the following (which seems to work):
for a, b, c in zip(*[iter(accounts_iter)]*3):
print(a)
print(b)
print(c)
accounts_iteris a list of tuples I created.iter(accounts_iter)unpacksaccounts_iterinto a list iterator, so its still a list of tuples just that its now iterable
Here's where I struggle to understand.
*[iter(accounts_iter)]unpacks the list inStep 2into separate tuples, so no longer a list of tuples but individual tuples*[iter(accounts_iter)]*3multiplies that by 3
In my output, I do not seem to have duplicates, but am indeed able to process 3 items each loop.
But won't I have 3 copies of the same tuple once zip(*[iter(accounts_iter)]*3) happens?
CodePudding user response:
Unwinding layers of "cleverness", you may find this equivalent spelling easier to follow:
x = iter(accounts_iter)
for a, b, c in zip(*[x, x, x]):
print(a, b, c)
which is, in turn, equivalent to the even less-clever:
x = iter(accounts_iter)
for a, b, c in zip(x, x, x):
print(a, b, c)
Now it should start to become clear. There is only a single iterator object, x. On each iteration, zip(), under the covers, calls next(x) 3 times, once for each iterator object passed to it. But it's the same iterator object here each time. So it delivers the first 3 next(x) results, and leaves the shared iterator object waiting to deliver its 4th result next. Lather, rinse, repeat.
BTW, I suspect you're parsing *[iter(accounts_iter)]*3 incorrectly in your head. The trailing *3 happens first, and then the prefix * is applied to the 3-element list *3 created. f(*iterable) is a shortcut for calling f() with a variable number of arguments, one for each object iterable delivers.
