Как преобразовать строковое представление списка в список?
Описание проблемы:
Я ищу самый простой способ преобразовать строковое представление списка, как в следующем примере, в объект типа 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)?
Удалить пустые строки из списка строк
Как проверить, является ли строка подстрокой элементов в списке строк?
Диапазон букв в Python
Преобразование всех строк в списке в целые числа