Как преобразовать строковое представление списка в список?
Описание проблемы:
Я ищу самый простой способ преобразовать строковое представление списка, как в следующем примере, в объект типа list
:
x = '[ "A","B","C" , " D"]'
Меня также интересует, как обработать случаи, когда пользователь добавляет пробелы между запятыми и пробелы внутри кавычек. В итоге мне нужно получить следующий результат:
x = ["A", "B", "C", "D"]
Я понимаю, что могу использовать методы strip()
и split()
, а также проверять на наличие неалфавитных символов. Однако код получается довольно громоздким. Существует ли какая-то быстрая функция, о которой я не знаю?
5 ответ(ов)
eval
является опасным методом, и не стоит выполнять ввод от пользователя.
Если у вас версия Python 2.6 или новее, предпочтительнее использовать модуль ast
вместо eval
:
>>> import ast
>>> ast.literal_eval('["A", "B", "C", " D"]')
["A", "B", "C", " D"]
После этого вы можете использовать метод strip
для обработки строк.
Если вы используете более старую версию Python, можно приблизиться к желаемому результату с помощью простого регулярного выражения:
>>> import re
>>> x = '[ "A", " B", "C", "D "]'
>>> re.findall(r'"\s*([^"]*?)\s*"', x)
['A', 'B', 'C', 'D']
Этот метод не так хорош, как вариант с ast
, так как, например, он не корректно обрабатывает экранированные кавычки в строках. Тем не менее, он прост, не требует опасного eval
, и может быть вполне достаточен для ваших целей, если вы используете более старую версию Python без ast
.
Существует быстрое решение:
x = eval('[ "A","B","C" , " D"]')
Чтобы удалить нежелательные пробелы в элементах списка, можно использовать следующий код:
x = [x.strip() for x in eval('[ "A","B","C" , " D"]')]
Обратите внимание, что использование eval
потенциально небезопасно, особенно если вы не контролируете входные данные. Рассмотрите возможность использования более безопасных методов, таких как модуль json
, для парсинга строк.
Вдохновившись некоторыми из приведенных выше ответов, которые работают с базовыми пакетами Python, я сравнил производительность нескольких методов (используя Python 3.7.3):
Метод 1: ast
import ast
list(map(str.strip, ast.literal_eval(u'[ "A","B","C" , " D"]')))
# ['A', 'B', 'C', 'D']
import timeit
timeit.timeit(stmt="list(map(str.strip, ast.literal_eval(u'[ \"A\",\"B\",\"C\" , \" D\"]')))", setup='import ast', number=100000)
# 1.292875313000195
Метод 2: json
import json
list(map(str.strip, json.loads(u'[ "A","B","C" , " D"]')))
# ['A', 'B', 'C', 'D']
import timeit
timeit.timeit(stmt="list(map(str.strip, json.loads(u'[ \"A\",\"B\",\"C\" , \" D\"]')))", setup='import json', number=100000)
# 0.27833264000014424
Метод 3: без импорта
list(map(str.strip, u'[ "A","B","C" , " D"]'.strip('][').replace('"', '').split(',')))
# ['A', 'B', 'C', 'D']
import timeit
timeit.timeit(stmt="list(map(str.strip, u'[ \"A\",\"B\",\"C\" , \" D\"]'.strip('][').replace('\"', '').split(',')))", number=100000)
# 0.12935059100027502
Меня разочаровало, что метод с наименьшей читаемостью оказался самым производительным... нужно учитывать компромиссы, когда вы выбираете наиболее читаемый вариант. Для типов задач, для которых я использую Python, я обычно ценю читаемость выше незначительно более производительного варианта, но, как всегда, это зависит от ситуации.
В вашем коде вы используете модуль ast
для безопасного парсинга строкового представления списка, а затем применяете метод strip()
к каждому элементу списка, чтобы удалить лишние пробелы. Вот объяснение вашего кода на русском:
import ast
# Используем ast.literal_eval для безопасного преобразования строки в список
l = ast.literal_eval('[ "A","B","C" , " D"]')
# Удаляем пробелы в начале и в конце каждого элемента списка
l = [i.strip() for i in l]
Этот код сначала создает список l
, содержащий элементы "A", "B", "C" и " D" (где " D" имеет пробел перед "D"). Затем с помощью спискового включения происходит итерация по каждому элементу l
, и метод strip()
удаляет пробел перед "D". В результате l
станет равным ["A", "B", "C", "D"]
.
Если у вас есть дополнительные вопросы или нужна помощь с другим кодом, не стесняйтесь спрашивать!
Если у вас есть только одномерный список, это можно сделать без импорта каких-либо библиотек:
x = u'[ "A","B","C" , " D"]'
ls = x.strip('[]').replace('"', '').replace(' ', '').split(',')
print(ls)
Результат будет:
['A', 'B', 'C', 'D']
Здесь мы сначала удаляем квадратные скобки с помощью strip('[]')
, затем убираем кавычки с помощью replace('"', '')
, и, наконец, удаляем пробелы с помощью replace(' ', '')
. После этого, используя метод split(',')
, мы разбиваем строку на отдельные элементы списка.
Почему используется string.join(list), а не list.join(string)?
Удалить пустые строки из списка строк
Как проверить, является ли строка подстрокой элементов в списке строк?
Как отсортировать список/кортеж списков/кортежей по элементу на заданном индексе
Вывод строки в текстовый файл