Во-первых, я не вижу причин откладывать разрыв цикла, если максимальная длина достигнута до следующей итерации.
Итак, изменяя ваш код, я придумываю следующий код:
s_tuples = [('Where are you',1),('What about the next day',2),('When is the next event',3)]
def get_words_number(s):
return len(s.split())
def truncate(s_tuples, max_length):
tot_len = 0
output = []
for s in s_tuples:
output.append(s[0])
tot_len += get_words_number(s[0])
if tot_len >= max_length:
break
return ' '.join(output)
print truncate(s_tuples,3)
Во-вторых, мне действительно не нравится, что создается временный объект output
. Мы можем передать метод join
с помощью итератора, который перебирает начальный список, не дублируя информацию.
def truncate(s_tuples, max_length):
def stop_iterator(s_tuples):
tot_len = 0
for s,num in s_tuples:
yield s
tot_len += get_words_number(s)
if tot_len >= max_length:
break
return ' '.join(stop_iterator(s_tuples))
print truncate(s_tuples,3)
Кроме того, в ваших примерах вывод немного больше, чем установленный максимум слов. Если вы хотите, чтобы количество слов всегда было меньше предела (но все же максимально возможного), чем просто поставить yield
после проверки на пределе:
def truncate(s_tuples, max_length):
def stop_iterator(s_tuples):
tot_len = 0
for s,num in s_tuples:
tot_len += get_words_number(s)
if tot_len >= max_length:
if tot_len == max_length:
yield s
break
yield s
return ' '.join(stop_iterator(s_tuples))
print truncate(s_tuples,5)