9

Как преобразовать строковое представление списка в список?

3

Описание проблемы:

Я ищу самый простой способ преобразовать строковое представление списка, как в следующем примере, в объект типа list:

x = '[ "A","B","C" , " D"]'

Меня также интересует, как обработать случаи, когда пользователь добавляет пробелы между запятыми и пробелы внутри кавычек. В итоге мне нужно получить следующий результат:

x = ["A", "B", "C", "D"]

Я понимаю, что могу использовать методы strip() и split(), а также проверять на наличие неалфавитных символов. Однако код получается довольно громоздким. Существует ли какая-то быстрая функция, о которой я не знаю?

5 ответ(ов)

1

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.

0

Существует быстрое решение:

x = eval('[ "A","B","C" , " D"]')

Чтобы удалить нежелательные пробелы в элементах списка, можно использовать следующий код:

x = [x.strip() for x in eval('[ "A","B","C" , " D"]')]

Обратите внимание, что использование eval потенциально небезопасно, особенно если вы не контролируете входные данные. Рассмотрите возможность использования более безопасных методов, таких как модуль json, для парсинга строк.

0

Вдохновившись некоторыми из приведенных выше ответов, которые работают с базовыми пакетами 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, я обычно ценю читаемость выше незначительно более производительного варианта, но, как всегда, это зависит от ситуации.

0

В вашем коде вы используете модуль 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"].

Если у вас есть дополнительные вопросы или нужна помощь с другим кодом, не стесняйтесь спрашивать!

0

Если у вас есть только одномерный список, это можно сделать без импорта каких-либо библиотек:

x = u'[ "A","B","C" , " D"]'
ls = x.strip('[]').replace('"', '').replace(' ', '').split(',')
print(ls)

Результат будет:

['A', 'B', 'C', 'D']

Здесь мы сначала удаляем квадратные скобки с помощью strip('[]'), затем убираем кавычки с помощью replace('"', ''), и, наконец, удаляем пробелы с помощью replace(' ', ''). После этого, используя метод split(','), мы разбиваем строку на отдельные элементы списка.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь