Format string height
Есть список строк взятый из файла:
data = ["Это текст имеет 27 символов", "Этот 16 символов", "а этот и сразу содержит 35 символов"]
Задача состоим втом чтобы отформатировать текст таким образом чтобы строка была растянута по ширине, заданной в count.
count = int(input())
out = []
for i in data:
out.append(i.center(35))
print(out)
При таком коде я получаю:
Это текст имеет 27 символов
Этот 16 символов
А хочу получать:
Это текст имеет 27 символов
Этот 16 символов
Ответы (2 шт):
Разбить строку на слова, подсчитать требуемое количество пробелов в каждом промежутке, слить слова с пробелами. Profit.
def justify(s, maxlen):
def spaces(l, n): # вычисляет нужное количество пробелов в каждом промежутке
# l - требуемое общее количество пробелов
# n - количество мест (промежутков между словами)
seq = [round(l/n)]
for i in range(2, n+1):
seq.append(round(l*i/n) - sum(seq))
return list(map(lambda x: " "*x, seq))
s = s.strip()
if len(s) >= maxlen:
return s
words = s.split(" ")
if len(words) < 2:
return s.center(maxlen)
return "".join(sum(zip(words, spaces(maxlen - sum(map(len, words)), len(words)-1) + [""]), ()))
data = ["Это текст имеет 27 символов",
"Этот 16 символов",
"а этот и сразу содержит 35 символов"]
for t in data:
r = justify(t, 35)
print(r, "=>", len(r))
Это текст имеет 27 символов => 35
Этот 16 символов => 35
а этот и сразу содержит 35 символов => 35
Вариант алгоритма как у @Рамис (пробелы распределены не равномерно, а слева больше), но вообще без использования циклов.
def justify(s, maxlen):
s = s.strip()
if len(s) >= maxlen:
return s
space_count = s.count(' ');
if not space_count:
return s.center(maxlen)
total_spaces = maxlen - len(s) + space_count
min_spaces = total_spaces // space_count
words = s.split(' ', round((total_spaces / space_count - min_spaces) * space_count))
words[-1] = words[-1].replace(' ', ' '*min_spaces)
return (' '*(min_spaces+1)).join(words)
Создаем список space_index с индексом каждого пробела в строке.
space_index = [index for index, char in enumerate(text) if char == ' ']
В строке, рядом с индексом пробела space_index[i] добавляем новый пробел.
text = text[:space_index[i]] + ' ' + text[space_index[i]:]
Изменяем список с индексом пробелов, так как тест изменился.
space_index = space_index[:i]+list(map(lambda x: x+1, space_index[i:]))
Выполняем это пока строка не станет длинной в 35 символов.
def my_func(data, count=35):
for text in data:
space_index = [index for index, char in enumerate(text) if char == ' ']
i = 0
while True:
if len(text) < count and len(space_index) > 0:
text = text[:space_index[i]] + ' ' + text[space_index[i]:]
space_index = space_index[:i]+list(map(lambda x: x+1, space_index[i:]))
i+=1
if i+1 > len(space_index):
i = 0
else:
break
print(text)
data = ["Это текст имеет 27 символов", "Этот 16 символов", "а этот и сразу содержит 35 символов", "aaaaaaaa"]
my_func(data, 35)
Ответ:
Это текст имеет 27 символов
Этот 16 символов
а этот и сразу содержит 35 символов
aaaaaaaa