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).
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 принимает любую итерируемую последовательность, а не только список. Это снимает вопрос про память на больших данных: можно склеивать генератор, и промежуточный список строк не появится вовсе.
def lines():
for i in range(1, 4):
yield f'строка {i}'
print('\n'.join(lines()))
строка 1 строка 2 строка 3
Наивная реализация join через цикл создаёт список из всех кусков — а потом склеивает его. То есть память на объём данных всё равно тратится, просто в виде списка. С генератором join этого не делает. Для файла в сто миллионов строк разница между «список из 100 миллионов строк» и «ничего» — это разница между «не влезает в память» и «работает».
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)))
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 + часть?
Список words = ['Строки', 'в', 'Python'] уже задан. Выведи его тремя способами: фразой через пробел, через дефисы и длину фразы с пробелами.
Как объединить список строк в одну строку в 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, ...).
Можно ли использовать join для чисел?
Нет — join требует строки и падает с TypeError: expected str instance, int found. Числа заранее превращают: ', '.join(map(str, nums)) или списком [str(n) for n in nums]. Если результат пойдёт обратно в числа, не склеивайте: считайте на числах и форматируйте только при выводе.
Понравился урок? Сошлитесь на него
«Естественный вопрос — а как собрать обратно?»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Строки · Урок 9
split: разобрать строку
Одна строка данных редко живёт одна: CSV-запись, строка лога, поля формы. Метод split режет строку по разделителю и возвращает список частей — разбираем все варианты, от запятой до splitlines.
Строки · Урок 11
Проверки строки: isdigit, isalpha и валидация ввода
Методы-вопросы: строка состоит только из цифр? только из букв? всё в нижнем регистре? Учимся валидировать ввод пользователя одним вызовом.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Множества · Урок 2
Создание множеств: {} и set() — литерал, список, строка
Два способа создать множество: литерал в фигурных скобках и set() от списка или строки. Пустые скобки — это словарь, поэтому пустое множество пишут set().
set от спискаset от строки
Циклы · Урок 12
Генератор списка в Python: цикл в одну строку
Цикл сбора списка — из трёх строк в одну: выражение, for, условие. Разбираем анатомию генератора списка, фильтр через if, превращение через if-else и границу, за которой однострочник вредит.
генератор списка pythonpython генератор списка с if
Строки · Урок 18
Строки и списки: перевод туда-обратно
Строка ведёт себя почти как список символов, но с одним запретом — на изменение. Учимся свободно переводить строку в список и обратно и использовать силу обоих миров.
python строка в списокpython список в строку