Иногда перед программистом встаёт задача преобразования итерируемого объекта (чаще всего списка) в строку. Как правило, это делается для отображения куда-либо: печать в консоль или запись в файл. Возможна и другая неочевидная причина перевести список в строку – использовать методы строки и функции, работающие с этим типом данных. К примеру, поиск по сложным условиям иногда проще реализовать через регулярные выражения.
В Python, если такое преобразование сделать «в лоб», получится некрасиво:
var = [1, '2', 3]
print(var)
print(str(var))
# Вывод:
[1, '2', 3]
[1, '2', 3]
А как сделать красиво Вы узнаете в этом уроке.
- Преобразование списка в строку методомjoin
- Почему join() — метод строки, а не списка?
- Разбитие строки с помощью join()
- Обратное преобразование строки в список
- Объединение списка с не строковыми типами данных
- Использование join() и map()
- Использование цикла
- Использование спискового включения
- Альтернативы методу join()
- Конкатенация
- Метод strip()
Преобразование списка в строку методом join
Чаще всего для преобразования списка в строку используют метод строки join() python. Этот метод принимает итерируемый объект в качестве аргумента. Напомню, что итерируемыми являются те объекты, элементы можно перебрать. К примеру, список, множество, кортеж и, кстати, строка.
Объект (строка), к которому применяется метод будет выступать в роли разделителя.
Вот как это работает:
var = ['1', '2', '3']
print(', '.join(var))
# Вывод:
1, 2, 3
Как видите, строка ‘, ‘ была вставлена между элементами списка var и таким образом сформирована новая строка, уже без квадратных скобок.
Есть одно серьёзное ограничение – все элементы, которые объединяются, должны иметь тип строки. Если это условие не соблюсти, интерпретатор вернёт исключение:
var = [1, 2, 3]
print(', '.join(var))
# Вывод:
Traceback (most recent call last):
File "C:\Users\Dushenko\AppData\Roaming\JetBrains\PyCharm2021.1\scratches\scratch.py", line 3, in <module>
print(', '.join(var))
TypeError: sequence item 0: expected str instance, int found
Process finished with exit code 1
Почему join() — метод строки, а не списка?
Синтаксис метода кажется немного неудобным. Почему бы не сделать так:
var = [1, 2, 3]
print(var.join(', '))
# Вывод:
Но нет…
Traceback (most recent call last):
File "C:\Users\Dushenko\AppData\Roaming\JetBrains\PyCharm2021.1\scratches\scratch.py", line 3, in <module>
print(var.join(', '))
AttributeError: 'list' object has no attribute 'join'
Process finished with exit code 1
У многих возникает вопрос: почему в Python метод join() реализован именно так? Почему он принадлежит типу строка?
Всё дело в том, что этот метод может работать с любым итерируемым объектом, а значит, если бы метод принадлежал итерируемому объекту, его пришлось бы реализовывать для каждого итерируемого типа. С другой стороны, разделитель – всегда строка и текущий синтаксис позволяет реализовать метод Python join() только для одного типа – строкового.
Разбитие строки с помощью join()
Я уже упоминал вначале что строки тоже можно итерировать. Это означает, что к ним данный метод тоже применим. Элементами последовательности в данном случае являются символы. Вот пример:
var = '123'
print(', '.join(var))
# Вывод:
1, 2, 3
Обратное преобразование строки в список
Если Вам необходимо произвести обратную операцию – создать список из строки, Вы можете использовать метод строки split(), который очень похож на join(). Вот простой пример:
var = '1, 2, 3'.split(', ')
print(var)
print('Тип:', type(var))
# Вывод:
['1', '2', '3']
Тип: <class 'list'>
Обратите внимание, что здесь порядок объект-аргумент обратный. Это означает, что строка, которую необходимо разбить, расположена слева, перед точкой, а разделитель передаётся как аргумент.
Объединение списка с не строковыми типами данных
Как уже говорилось ранее, все элементы списка должны быть строками. Если необходимо применить метод join(), но данное условие не выполняется, придётся выполнить приведение типа.
Использование join() и map()
Функция map() принимает два позиционных аргумента: первый аргумент – это функция, которую надо применить к каждому элементу последовательности; второй элемент – последовательность, к которой применяется функция. Возвращает функция специальный объект-итератор, поэтому, чтобы получить результаты, этот объект надо преобразовать к списку.
Пример использования функции map():
var = [1, 2, 3]
var = map(print, var)
print('var:', var)
var = list(var)
print('var:', var)
# Вывод:
var: <map object at 0x00000255FF652F40>
1
2
3
var: [None, None, None]
Как видите, функция map() вернула итератор map object, а в процессе преобразования к списку применила функцию print() к каждому элементу исходного списка.
Вернёмся к join(). Мы говорили о случае, когда надо преобразовать элементы не строкового типа к строковому. Вот как это делается с функцией map():
var = [1, 2, 3]
var = map(str, var)
print(', '.join(var))
# Вывод:
1, 2, 3
Использование цикла
Альтернативой может быть применение цикла:
var = [1, 2, 3]
new_var = []
for item in var:
new_var.append(str(item))
print(', '.join(new_var))
# Вывод:
1, 2, 3
Такой вариант хорошо подойдёт, если Вы знакомы только с базовыми конструкциями Питона.
Использование спискового включения
Ещё один вариант преобразования типа элементов последовательности:
var = [1, 2, 3]
print(', '.join([str(item) for item in var]))
# Вывод:
1, 2, 3
Лично я считаю вариант с функцией map() самым оптимальным. Как минимум, он быстрее всего работает. Списковое включение хорошо подходит для работы в консоли.
Альтернативы методу join()
Python предоставляет и другие способы добиться того же результата, что и от метода join().
Конкатенация
Конкатенация – это объединение строк. Выполняется при помощи символа «+».
Можно использовать низкоуровневый (императивный) подход и собственноручно написать алгоритм, имитирующий join(). Для этого используем конкатенацию:
var = [1, 2, 3]
str_var = ''
for item in var:
str_var += str(item) + ', '
str_var = str_var[:-2]
print(str_var)
# Вывод:
1, 2, 3
Конечно, это многословно и будет работать намного медленнее, так что я рекомендую воспринять это исключительно как упражнение.
Метод strip()
Давайте вернёмся в самое начало и вспомним как выглядит список, если его преобразовать в строку:
var = [1, 2, 3]
print(var)
# Вывод:
[1, 2, 3]
Если вы хотите получить разделенные запятой строки, можно использовать метод строки strip() и удалить квадратные скобки:
var = [1, 2, 3]
print(str(var).strip('[]'))
# Вывод:
1, 2, 3
Но, если в списке будут строки или ещё какие-то типы, кроме числовых, надо будет совершать дополнительные действия по очистке строки. Можно сказать, что это плохой, негибкий код. Просто знайте, что такая возможность есть.
var = [1, '2', complex(3)]
print(str(var).strip('[]'))
# Вывод:
1, '2', (3+0j)