Reputation: 571
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
head = 'head'
tail = 'tail'
suppose we can and can only get the iterator of some iterable(L). and we can not know the length of L. Is that possible to print the iterable as:
'head123tail'
'head456tail'
'head789tail'
'head10tail'
My try at it is as follows.
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
head = 'head'
tail = 'tail'
slice_size = 3
i = iter(L)
try:
while True:
counter = 0
while counter < slice_size:
e = next(i)
if counter == 0:
print(head, end='')
print(e, end='')
counter += 1
else:
print(tail)
except StopIteration:
if counter > 0:
print(tail)
Upvotes: 0
Views: 235
Reputation: 82899
You can split the iterator into chunks of three, using chain
and slice
from itertools
and a for
loop, and then join them. The for
loop will do most of what your try/while True/except
construct is doing.
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
head = 'head'
tail = 'tail'
slice_size = 3
iterator = iter(L)
from itertools import chain, islice
for first in iterator:
chunk = chain([first], islice(iterator, slice_size - 1))
print(head, ''.join(str(x) for x in chunk), tail)
However, if your iterator is just a list
, you can just use range
with a step
parameter:
for start in range(0, len(L), slice_size):
chunk = L[start : start + slice_size]
print(head, ''.join(str(x) for x in chunk), tail)
Upvotes: 1
Reputation: 78546
Here's one way to do it with itertools.groupby
and itertools.count
.
groupby
on the key function lambda _: next(c)//3
groups the items in the iterables in threes in successions. The logic uses the integer division of the next object in the count item on 3:
from itertools import groupby, count
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
head = 'head'
tail = 'tail'
c = count()
for _, g in groupby(L, lambda _: next(c)//3):
item = head + ''.join(map(str, g)) + tail
print(item)
Output:
head123tail
head456tail
head789tail
head10tail
Upvotes: 2