2016-10-15 2 views
0
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
head = 'head' 
tail = 'tail' 

Предположим, мы можем и можем получить только итератор некоторого итерируемого (L). и мы не можем знать длину L. Это можно напечатать итерацию как:как напечатать этот шаблон, используя итератор python

'head123tail' 
'head456tail' 
'head789tail' 
'head10tail' 

Мой попробовать на это следующим образом.

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) 
+0

Вы должны буфер вашей «головы», и распечатать его только после следующего преуспел, поскольку вы не можете предсказать, что будет дальше в итераторе, не потребляя его. –

+0

@ Жак, спасибо за ваше предложение. Я изменяю свой предварительный вопрос. – minion

ответ

2

Вот один из способов сделать это с itertools.groupby и itertools.count.

groupby на ключевых функции lambda _: next(c)//3 групп элементов в итерируемых в тройках в последовательностях. Логика использует целочисленное деление следующего объекта в счетный пункт на 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) 

Выход:

head123tail 
head456tail 
head789tail 
head10tail 
+0

Это очень интересное приложение 'groupby' и' count'. Вы также можете опубликовать это как ответ на [this] (http://stackoverflow.com/questions/24527006/split-a-generator-into-chunks-without-pre-walking-it) более общий вопрос. –

+0

Я не знаю, как выбрать между двумя текущими ответами. Поэтому я 'timeit'. Я запускал их на своем медленном компьютере 1000 раз. Ответ Коледоя получил 2.9803745844324028 секунд; Tobias_k получает 8.567057737782685 секунд. – minion

+0

@tobias_k Спасибо за указатель. Добавлен ответ: http://stackoverflow.com/a/40063403/3125566 –

1

Вы можете split the iterator into chunks из трех, используя chain и slice от itertools и for и присоедините их. Цикл for сделает большую часть вашей конструкции try/while True/except.

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) 

Однако, если итератор просто list, вы можете просто использовать range с step параметра:

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) 
Смежные вопросы