Перейти к содержанию

412 уроков, 25 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 10 из 20 Начальный 20 мин 120 XP

join: собрать строку из частей

split разбирает строку на части, join собирает обратно: разделитель, список строк — и одна готовая строка вместо десяти склеек плюсом. Разбираем синтаксис и главный вопрос: почему не плюс.

Редакция Питоники

В уроке 9 split разрезал строку на список частей. Естественный вопрос — а как собрать обратно? И не только обратно: список слов часто нужно превратить в фразу, колонки таблицы — в CSV-строку, куски пути — в адрес. Это работа метода join, обратной пары к split.

разделитель.join(список)

Запись join непривычна: метод вызывается у разделителя, а список передаётся аргументом. Читается так: «возьми эту строку-клей и склей ею элементы списка»:

список слов в фразу
words = ['собрать', 'фразу', 'из', 'слов']
print(' '.join(words))
print('-'.join(words))
print(''.join(words))
Вывод
собрать фразу из слов
собрать-фразу-из-слов
собратьфразуизслов

Один список, три результата: с пробелом получилась фраза, с дефисом — составное слово, а с пустым разделителем '' части склеились вплотную. Разделитель вставляется между элементами — ни в начале, ни в конце лишнего клея не останется.

внутри join — только строки

join требует, чтобы каждый элемент был строкой. Число среди строк останавливает его с ошибкой:

число посреди строк
try:
    print(', '.join(['кот', 3, 'ток']))
except TypeError as e:
    print('Ошибка:', e)
Вывод
Ошибка: sequence item 1: expected str instance, int found
числа превращены в строки
prices = [str(1250), str(300), str(80)]
print(' + '.join(prices))
Вывод
1250 + 300 + 80

почему join, а не плюс

Склеить пару строк плюсом легко — так вы делали это в уроке 1. Но помните: строки неизменяемы, и каждая склейка создаёт новую строку, копируя всё накопленное. В цикле из тысячи кусков плюс скопирует текст тысячу раз — работа растёт как квадрат числа кусков. join выделяет память под результат один раз и копирует каждую часть тоже один раз.

пять строк лога в одну
log_lines = [
    '2026-03-14 вход',
    '2026-03-14 поиск',
    '2026-03-14 корзина',
    '2026-03-14 оплата',
    '2026-03-14 выход',
]
print('\n'.join(log_lines))
Вывод
2026-03-14 вход
2026-03-14 поиск
2026-03-14 корзина
2026-03-14 оплата
2026-03-14 выход

Пять строк лога склеены переводами строк \n обратно в один текст. На пяти элементах разница с плюсом незаметна, на пяти тысячах join выигрывает в разы — поэтому правило простое: собираешь много кусков — бери join.

join — обратная пара к split

Методы работают в паре: split разрезает строку по разделителю в список, join склеивает список тем же или новым разделителем. Так меняют разделитель в данных:

разрезал и собрал заново
path = '2026/03/14'
parts = path.split('/')
print(parts)
print('/'.join(parts))
print('-'.join(path.split('/')))
Вывод
['2026', '03', '14']
2026/03/14
2026-03-14

Первая пара вызовов вернула дату как была: '/'.join собрал куски тем же слэшем. Вторая собрала уже дефисами — формат даты сменился одной строкой кода. Круговой приём «split, обработай части, join обратно» — основа чистки данных: strip для краёв и replace для середины работают по одному элементу за раз.

join и одиночная строка

join подходит не только к спискам, а к любой последовательности строк — например, к самой строке, ведь она последовательность символов. Разделитель встанет между каждыми двумя символами:

разделитель между символами
print('-'.join('кот'))
print('.'.join('py'))
Вывод
к-о-т
p.y

Карточка метода

ВызовРезультатЗаметка
' '.join(['а', 'б'])'а б'разделитель между элементами
''.join(['а', 'б'])'аб'пустой клей склеивает вплотную
', '.join([])''пустой список — пустая строка, без ошибок
', '.join(['а', 1])TypeErrorчисла заранее через str()
'-'.join('кот')'к-о-т'строка — последовательность символов

Пара split и join закрывает цикл обработки текста: разобрать, почистить, собрать. Другой способ вставлять значения в текст — f-строки из урока 3; для готовых списков удобнее join, для шаблонов с переменными — f-строки.

Как объединить список строк в одну: join

Если split разбирает строку на части, то join собирает части обратно. Синтаксис выглядит непривычно, потому что метод вызывается у разделителя, а список передаётся аргументом: ' '.join(words). Читается это как инструкция: «возьми эту строку-клей и склей ею элементы списка». Обратный вариант — words.join(' ') — не существует вовсе, и это не опечатка, а сознательный выбор в языке.

один список — три разных склейки
words = ['собрать', 'фразу', 'из', 'слов']
print(' '.join(words))
print('-'.join(words))
print(''.join(words))
Вывод
собрать фразу из слов
собрать-фразу-из-слов
собратьфразуизслов

Ключевая деталь, которую стоит проговорить: разделитель вставляется МЕЖДУ элементами и только между ними. Ни в начале, ни в конце лишнего клея не будет. Отсюда растёт классическая ошибка новичков: ', '.join(words) + ',' — «чтобы запятая была и в конце». Так делают, когда собирают SQL-запрос или CSV, и получают лишний разделитель, который ломает парсер на той стороне. Если разделитель нужен и в конце — собирайте список с заранее добавленным элементом.

Почему join, а не сложение в цикле

Это место, где Python раскрывает свою природу. Строки неизменяемы, поэтому s = s + часть не дописывает к существующей строке, а создаёт новую — и копирует старую целиком. Сто частей означают сто копирований уже накопленного текста: суммарно обрабатывается примерно половина всех данных × количество частей. join же сразу считает суммарную длину, выделяет память один раз и копирует каждый кусок ровно один раз.

На пяти элементах разницу не видно, и это ловушка: код с += в цикле работает годами, потому что данных мало. Потом выгрузка растёт до сотен тысяч строк, и процесс уезжает в память. Профилировщик показывает, что 90% времени уходит на копирование строк, которых никто не просил копировать. Лечение — одна строка: ' '.join(lines).

сборка CSV-строки
rows = [['хлеб', '45'], ['молоко', '89']]
csv = []
for name, price in rows:
    csv.append(','.join([name, price]))
print('\n'.join(csv))
Вывод
хлеб,45
молоко,89

Обратите внимание на два уровня join. Внутренний склеивает поля одной строки запятой, внешний — готовые строки переводом строки. Обычно это выглядит некрасиво и в реальном коде заменяется на модуль csv, который сам экранирует запятые и кавычки внутри значений: csv.writer знает, что поле с запятой надо заключить в кавычки. Ручной join этого не делает — и на данных вроде «ООО Ромашка, Тверь» вы получите битый CSV.

ЗадачаКак написатьЗамечание
Склеить слова через пробел' '.join(words)Самый частый случай
Склеить вплотную''.join(chars)Обратно к list(s)
Собрать CSV-строку','.join(fields)Для значений с запятыми — csv
Склеить с переводом строки'\n'.join(lines)Один проход вместо цикла
Соединить словари', '.join(f'{k}={v}' for ...)Через генератор f-строк
Склеить числа', '.join(map(str, nums))Числа → строки заранее

join и генераторы: не обязательно список

join принимает любую итерируемую последовательность, а не только список. Это снимает вопрос про память на больших данных: можно склеивать генератор, и промежуточный список строк не появится вовсе.

join по генератору
def lines():
    for i in range(1, 4):
        yield f'строка {i}'

print('\n'.join(lines()))
Вывод
строка 1
строка 2
строка 3

Наивная реализация join через цикл создаёт список из всех кусков — а потом склеивает его. То есть память на объём данных всё равно тратится, просто в виде списка. С генератором join этого не делает. Для файла в сто миллионов строк разница между «список из 100 миллионов строк» и «ничего» — это разница между «не влезает в память» и «работает».

join по строке и по списку
letters = ['к', 'о', 'т']
print(''.join(letters))
print(''.join(letters[::-1]))
print('.'.join(reversed(letters)))
Вывод
кот
ток
т.о.к

Три строки — три способа развернуть текст. Первые две используют срез letters[::-1] из урока про срезы, третья — функцию reversed, которая работает с любой последовательностью и не копирует её. Для списка из миллиона элементов разница между срезом и reversed в памяти заметна.

И замыкаем круг: пара split и join — это основа чистки данных. Разрезать, обработать каждый кусок, собрать обратно. Именно так нормализуют разделители, убирают лишние пробелы и приводят формат к единому виду. В следующих уроках мы разберём проверки содержимого, форматирование и работу с многострочными текстами — все они опираются на этот же приём.

join склеивает элементы списка в одну строку, вставляя разделитель между ними; пустой разделитель собирает текст вплотную, а в цикле join быстрее плюса.

Что выведет код?

Сначала предскажи ответ в голове — это главный навык программиста.

words = ['Строки', 'в', 'Python']
print(' '.join(words))
print(', '.join(['а', 'б']))
print(''.join(['а', 'б']))
path = 'src/lib/str.py'
parts = path.split('/')
print('/'.join(reversed(parts)))
Проверь себя
0 / 8

1. Как склеить список слов ['раз', 'два'] в строку «раз-два»?

2. Что вернёт ''.join(['кот', 'код'])?

3. Что произойдёт при ', '.join(['а', 2, 'в'])?

4. Почему для сборки тысячи кусков рекомендуют join, а не плюс в цикле?

5. Что вернёт '-'.join('кот')?

6. path = '2026/03/14'. Что вернёт '-'.join(path.split('/'))?

7. Что вернёт ', '.join(['а', 'б', 'в'])?

8. Почему join() по списку из 100000 элементов быстрее, чем цикл с s = s + часть?

Карточки терминов
Запомнено: 0 / 7
Практика

Список words = ['Строки', 'в', 'Python'] уже задан. Выведи его тремя способами: фразой через пробел, через дефисы и длину фразы с пробелами.

practice.py
Вопросы и ответы по уроку

Как объединить список строк в одну строку в Python?

Методом join, вызванным у разделителя: ' '.join(words) соберёт слова через пробел, ''.join(части) — вплотную. Разделитель вставляется только между элементами, без лишнего в начале и конце.

Урок 9: split

Почему join вызывается у строки, а не у списка?

Так задуман синтаксис: метод принадлежит строке-разделителю, и это позволяет склеивать им любую последовательность строк — список, кортеж, даже символы другой строки. Читается вызов как команда: «разделитель, собери эти части».

Join выдаёт TypeError: expected str instance — что делать?

В последовательности есть не-строка, чаще всего число. Превратите элементы в строки перед склейкой: для маленьких списков вручную через str(), для больших — map(str, числа) или генератор списков [str(n) for n in числа].

Что быстрее: конкатенация плюсом или join?

Для двух-трёх известных строк разницы нет. В цикле join опережает плюс в разы: строка неизменяема, и каждый s = s + кусок копирует всё накопленное заново, тогда как join распределяет память один раз. Чем больше кусков, тем заметнее выигрыш.

Урок 1: строки как данные

Как объединить список строк в одну строку в Python?

Методом join, вызванным у разделителя: ' '.join(words) соберёт слова через пробел, ''.join(parts) — вплотную. Разделитель вставляется только между элементами, без лишнего в начале и конце. Внутри списка должны быть только строки — числа сначала превращают через str() или map(str, ...).

Урок 9: split

Можно ли использовать join для чисел?

Нет — join требует строки и падает с TypeError: expected str instance, int found. Числа заранее превращают: ', '.join(map(str, nums)) или списком [str(n) for n in nums]. Если результат пойдёт обратно в числа, не склеивайте: считайте на числах и форматируйте только при выводе.

Понравился урок? Сошлитесь на него

«Естественный вопрос — а как собрать обратно?»

Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Что дальше

Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.