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

Часто желательно изменить поведение существующих базовых кодов путем переноса или замены функций. При редактировании исходного кода эти функции являются жизнеспособным вариантом, это может быть прямолинейный процесс. Если источник функций не может быть отредактирован (например, если функции предоставлены библиотекой системы C), тогда требуются альтернативные методы. Здесь мы представляем такие методы для платформ UNIX, Windows и Macintosh OS X.

blockquote>

Это отличный PDF-материал, описывающий, как это было сделано в OS X, Linux и Windows.

У этого нет никаких удивительных трюков, которые не были зарегистрированы здесь (это удивительный набор ответов BTW) ... но это приятное чтение.

Перехват произвольных функции на платформах Windows, UNIX и Macintosh OS X (2004), Daniel S. Myers и Adam L. Bazinet .

Вы можете загрузить PDF непосредственно из альтернативного местоположения (для избыточности) .

И, наконец, если предыдущие два источника каким-то образом опустились в пламя, вот результат поиска Google для него .

423
задан martineau 21 March 2018 в 16:36
поделиться

8 ответов

>>> import ast
>>> x = u'[ "A","B","C" , " D"]'
>>> x = ast.literal_eval(x)
>>> x
['A', 'B', 'C', ' D']
>>> x = [n.strip() for n in x]
>>> x
['A', 'B', 'C', 'D']

ast.literal_eval :

С помощью ast.literal_eval можно безопасно оценить узел выражения или строку, содержащую выражение Python. Предоставленная строка или узел могут состоять только из следующих литеральных структур Python: строк, чисел, кортежей, списков, диктов, логических значений и None.

619
ответ дан Community 21 March 2018 в 16:36
поделиться

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

1
ответ дан kinzleb 21 March 2018 в 16:36
поделиться

Не импортируя ничего:

>>> x = u'[ "A","B","C" , " D"]'
>>> ls = x.strip('[]').replace('"', '').replace(' ', '').split(',')
>>> ls
['A', 'B', 'C', 'D']
5
ответ дан ruohola 21 March 2018 в 16:36
поделиться

If you know that your lists only contain quoted strings, this pyparsing example will give you your list of stripped strings (even preserving the original Unicode-ness).

>>> from pyparsing import *
>>> x =u'[ "A","B","C" , " D"]'
>>> LBR,RBR = map(Suppress,"[]")
>>> qs = quotedString.setParseAction(removeQuotes, lambda t: t[0].strip())
>>> qsList = LBR + delimitedList(qs) + RBR
>>> print qsList.parseString(x).asList()
[u'A', u'B', u'C', u'D']

If your lists can have more datatypes, or even contain lists within lists, then you will need a more complete grammar - like this one on the pyparsing wiki, which will handle tuples, lists, ints, floats, and quoted strings. Will work with Python versions back to 2.4.

4
ответ дан 22 November 2019 в 22:55
поделиться

Assuming that all your inputs are lists and that the double quotes in the input actually don't matter, this can be done with a simple regexp replace. It is a bit perl-y but works like a charm. Note also that the output is now a list of unicode strings, you didn't specify that you needed that, but it seems to make sense given unicode input.

import re
x = u'[ "A","B","C" , " D"]'
junkers = re.compile('[[" \]]')
result = junkers.sub('', x).split(',')
print result
--->  [u'A', u'B', u'C', u'D']

The junkers variable contains a compiled regexp (for speed) of all characters we don't want, using ] as a character required some backslash trickery. The re.sub replaces all these characters with nothing, and we split the resulting string at the commas.

Note that this also removes spaces from inside entries u'["oh no"]' ---> [u'ohno']. If this is not what you wanted, the regexp needs to be souped up a bit.

6
ответ дан 22 November 2019 в 22:55
поделиться
import ast
l = ast.literal_eval('[ "A","B","C" , " D"]')
l = [i.strip() for i in l]
12
ответ дан 22 November 2019 в 22:55
поделиться

There is a quick solution:

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

Unwanted whitespaces in the list elements may be removed in this way:

x = [x.strip() for x in eval('[ "A","B","C" , " D"]')]
8
ответ дан 22 November 2019 в 22:55
поделиться

The eval is dangerous - you shouldn't execute user input.

If you have 2.6 or newer, use ast instead of eval:

>>> import ast
>>> ast.literal_eval('["A","B" ,"C" ," D"]')
["A", "B", "C", " D"]

Once you have that, strip the strings.

If you're on an older version of Python, you can get very close to what you want with a simple regular expression:

>>> x='[  "A",  " B", "C","D "]'
>>> re.findall(r'"\s*([^"]*?)\s*"', x)
['A', 'B', 'C', 'D']

This isn't as good as the ast solution, for example it doesn't correctly handle escaped quotes in strings. But it's simple, doesn't involve a dangerous eval, and might be good enough for your purpose if you're on an older Python without ast.

74
ответ дан 22 November 2019 в 22:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: