Зарегистрируйтесь, чтобы продолжить обучение

Генерация строки в цикле Python: Списки

Генерация строк в циклах — задача, часто возникающая на практике. Типичный пример — функция, помогающая генерировать HTML-списки. Она принимает на вход коллекцию элементов и возвращает HTML-список из них:

coll = ['milk', 'butter']

build_HTML_list(coll)
# <ul><li>milk</li><li>butter</li></ul>

Как можно решить эту задачу в лоб:

  1. Создать переменную result и записать в нее <ul>.
  2. Пройтись циклом по элементам коллекции и дописать в результирующую строку очередной элемент <li>.
  3. Добавить в конце </ul> и вернуть result из функции.
def build_HTML_list(coll):
  result = '<ul>'
  for item in coll:
    result = f'{result}<li>{item}</li>'
    # либо так: result += '<li>{item}</li>'
  result = f'{result}</ul>'

  return result

coll = ['milk', 'butter']

print(build_HTML_list(coll))
# => <ul><li>milk</li><li>butter</li></ul>

Такой способ вполне рабочий, но для большинства языков программирования максимально неэффективный. Дело в том, что конкатенация и интерполяция порождают новую строчку вместо старой. Подобная ситуация повторяется на каждой итерации. Причем строка становится все больше и больше. Копирование строк приводит к серьезному расходу памяти и может влиять на производительность. Конечно, для большинства приложений данная проблема неактуальна из-за малого объема прогоняемых данных, но более эффективный подход не сложнее в реализации и обладает рядом плюсов. Поэтому стоит сразу приучить себя работать правильно.

Правильно, в случае с динамическими языками – формировать список, который затем с помощью метода join() можно превратить в строку:

def build_HTML_list(coll):
  parts = []
  for item in coll:
    parts.append(f'<li>{item}</li>')

  # Метод join объединяет элементы списка в строку
  # В качестве разделителя между значениями
  # используется значение строки
  inner_value = ''.join(parts)
  result = f'<ul>{inner_value}</ul>'
  return result

Размер кода практически не изменился, но способ формирования результата стал другим. Вместо строки, сначала собирается список, который затем превращается в строку с помощью метода .join(). У такого подхода есть и дополнительные плюсы:

  • Такой код проще отлаживать. Данные, представленные списком, легче вычленять визуально и программно.
  • Список — это структура, с ним можно производить дополнительные манипуляции. С готовой строкой уже ничего особо не сделать.

Регулируя разделитель, строки можно объединять разными способами. Например, через запятую с пробелом:

parts = ['python', 'PHP', 'Python']
output = ', '.join(parts)

print(output) # => python, PHP, Python

Если каждое слово надо вывести на новой строчке, то в качестве разделителя используем символ перевода строки '\n':

parts = ['python', 'PHP', 'Python']

# Теперь каждое слово будет начинаться с новой строки
output = '\n'.join(parts)

print(output)
# => python
# => PHP
# => Python

Последний пример особенно важен. Новички часто допускают ошибку и добавляют перевод строки в момент формирования списка, а не в join(). Посмотрите на пример с нашей функцией build_HTML_list().

Правильно:

def build_HTML_list(coll):
  parts = []
  for item in coll:
    parts.append(f'<li>{item}</li>')
  inner_value = '\n'.join(parts) # перевод строки
  result = f'<ul>{inner_value}</ul>'
  return result

coll = ['milk', 'butter']

build_HTML_list(coll)
print # => <ul><li>milk</li>
print # => <li>butter</li></ul>

Неправильно:

def build_HTML_list(coll):
  parts = []
  for item in coll:
    parts.append(f'\n<li>{item}</li>')
  inner_value = ''.join(parts) # разделителя нет
  result = f'<ul>{inner_value}</ul>'
  return result

coll = ['milk', 'butter']

build_HTML_list(coll)
print # => <ul>
print # => <li>milk</li>
print # => <li>butter</li></ul>

Дополнительные материалы

  1. Джоэль Спольски. Назад к основам (английская версия)

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 26 декабря
профессия
от 24 542 ₸ в месяц
новый
Сбор, анализ и интерпретация данных
9 месяцев
с нуля
Старт 26 декабря

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»