wake-up-neo.net

Konvertieren Sie die Stringdarstellung der Liste in die Liste

Ich habe mich gefragt, was der einfachste Weg ist, eine string-Liste wie die folgende in eine list zu konvertieren:

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

Selbst wenn der Benutzer Leerzeichen zwischen die Kommas und Leerzeichen in die Anführungszeichen setzt. Ich muss damit umgehen, um:

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

in Python.

Ich weiß, dass ich Leerzeichen mit strip() und split() mit dem Split-Operator entfernen und auf Nicht-Alphabete prüfen kann. Aber der Code wurde sehr kludig. Gibt es eine schnelle Funktion, die mir nicht bekannt ist?

356
harijay
>>> 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 :

Mit ast.literal_eval können Sie einen Ausdrucksknoten oder eine Zeichenfolge, die einen Python-Ausdruck enthält, sicher auswerten. Die bereitgestellte Zeichenfolge oder der angegebene Knoten dürfen nur aus den folgenden Python-Literalstrukturen bestehen: Zeichenfolgen, Zahlen, Tupel, Listen, Dicts, Booleans und None.

557
Roger Pate

Die eval ist gefährlich - Sie sollten keine Benutzereingaben ausführen.

Wenn Sie über 2.6 oder neuer verfügen, verwenden Sie anstelle von eval ein ast:

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

Sobald Sie das haben, strip die Zeichenfolgen.

Wenn Sie eine ältere Version von Python verwenden, können Sie mit einem einfachen regulären Ausdruck dem, was Sie möchten, sehr nahe kommen:

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

Dies ist nicht so gut wie die ast-Lösung, zum Beispiel kann es nicht korrekt mit Anführungszeichen in Strings umgehen. Aber es ist einfach, beinhaltet keine gefährliche Bewertung und könnte für Ihren Zweck gut genug sein, wenn Sie einen älteren Python ohne Ast verwenden.

69
Mark Byers

Das json -Modul ist eine bessere Lösung, wenn es eine stringified - Liste von Wörterbüchern gibt. Mit der Funktion json.loads(your_data) kann es in eine Liste umgewandelt werden.

>>> import json
>>> x = u'[ "A","B","C" , " D"]'
>>> json.loads(x)
[u'A', u'B', u'C', u' D']

Ähnlich 

>>> x = u'[ "A","B","C" , {"D":"E"}]'
>>> json.loads(x)
[u'A', u'B', u'C', {u'D': u'E'}]
52
Ryan
import ast
l = ast.literal_eval('[ "A","B","C" , " D"]')
l = [i.strip() for i in l]
12
tosh

Es gibt eine schnelle Lösung:

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

Unerwünschte Leerzeichen in den Listenelementen können auf folgende Weise entfernt werden:

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

Vorausgesetzt, dass alle Ihre Eingaben Listen sind und die Anführungszeichen in der Eingabe eigentlich keine Rolle spielen, können Sie dies mit einem einfachen Regex-Ersetzen tun. Es ist ein bisschen Perl-y, funktioniert aber wie ein Zauber. Beachten Sie auch, dass die Ausgabe jetzt eine Liste von Unicode-Zeichenfolgen ist. Sie haben nicht angegeben, dass Sie dies benötigen, aber angesichts der Unicode-Eingabe scheint das sinnvoll zu sein.

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']

Die Junker-Variable enthält einen kompilierten Regex (für die Geschwindigkeit) aller Zeichen, die wir nicht wollen, wobei] als Zeichen ein Backslash-Trickspiel benötigt. Der re.sub ersetzt alle diese Zeichen durch nichts und wir teilen die resultierende Zeichenfolge bei den Kommas 

Beachten Sie, dass dadurch auch Leerzeichen aus den Einträgen u '["oh nein"]' ---> [u'ohno '] entfernt werden. Wenn dies nicht das ist, was Sie wollten, muss der Regex etwas aufgemischt werden. 

7
dirkjot

mit numpy funktioniert dies auf sehr einfache Weise

x = u'[ "A","B","C" , " D"]'
list_string = str(x)
import numpy as np
print np.array(list_string)

gibt

>>> 
[ "A","B","C" , " D"]
6
octoback

Wenn Sie wissen, dass Ihre Listen nur Strings in Anführungszeichen enthalten, erhalten Sie in diesem Beispiel eine Liste mit entfernten Strings (auch wenn die ursprüngliche Unicode-Eigenschaft erhalten bleibt).

>>> 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']

Wenn Ihre Listen mehr Datentypen haben oder sogar Listen enthalten können, benötigen Sie eine vollständigere Grammatik - wie this im pyparsing-Wiki, das Tupel, Listen, Ints, Floats und Strings in Anführungszeichen behandelt . Funktioniert mit Python-Versionen bis 2.4.

3
PaulMcG

Ohne etwas zu importieren;

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

ls = x.strip('][').split(',')
3
ruohola

Um die Antwort von @Ryan mit json weiter zu vervollständigen, ist eine der Funktionen zum Konvertieren von Unicode die folgende: https://stackoverflow.com/a/13105359/7599285

ex mit doppelten oder einfachen Anführungszeichen:

>print byteify(json.loads(u'[ "A","B","C" , " D"]')
>print byteify(json.loads(u"[ 'A','B','C' , ' D']".replace('\'','"')))
['A', 'B', 'C', ' D']
['A', 'B', 'C', ' D']
2
CptHwK

Nach all den Antworten beschloss ich, die gebräuchlichsten Methoden festzulegen:

from time import time
import re
import json


my_str = str(list(range(19)))
print(my_str)

reps = 100000

start = time()
for i in range(0, reps):
    re.findall("\w+", my_str)
print("Regex method:\t", (time() - start) / reps)

start = time()
for i in range(0, reps):
    json.loads(my_str)
print("json method:\t", (time() - start) / reps)

start = time()
for i in range(0, reps):
    ast.literal_eval(my_str)
print("ast method:\t\t", (time() - start) / reps)

start = time()
for i in range(0, reps):
    [n.strip() for n in my_str]
print("strip method:\t", (time() - start) / reps)



    regex method:    6.391477584838867e-07
    json method:     2.535374164581299e-06
    ast method:      2.4425282478332518e-05
    strip method:    4.983267784118653e-06

Am Ende gewinnt Regex!

1
passs

Ich würde gerne eine intuitivere Musterungslösung mit Regex bereitstellen. .__ Die folgende Funktion nimmt eine stringifizierte Liste mit beliebigen Zeichenfolgen als Eingabe. 

Schrittweise Erklärung: Sie entfernen alle Whitespacing-, Bracketing- und value_separators-Werte (sofern sie nicht Teil der Werte sind, die Sie extrahieren möchten, andernfalls wird die Regex komplexer). Dann teilen Sie die gelöschte Zeichenfolge in einfache oder doppelte Anführungszeichen auf und übernehmen die nicht leeren Werte (oder ungerade indizierte Werte, unabhängig von der Einstellung). 

def parse_strlist(sl):
import re
clean = re.sub("[\[\],\s]","",sl)
splitted = re.split("[\'\"]",clean)
values_only = [s for s in splitted if s != '']
return values_only

testsample : "['21'," foo "'6', '0'," A "]"

1

Nehmen wir an, Ihr String ist t_vector = [34, 54, 52, 23] und Sie möchten diesen in eine Liste konvertieren. Sie können die folgenden 2 Schritte verwenden:

ls = t_vector.strip('][')
t_vector = ls.split(' ')

t_vector enthält die Liste.

0
Coding bat

Inspiriert von einigen der obigen Antworten, die mit Basis-Python-Paketen funktionieren, habe ich die Leistung einiger weniger verglichen (unter Verwendung von Python 3.7.3):

Methode 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

Methode 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

Methode 3: kein Import

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

Ich war enttäuscht zu sehen, dass ich die Methode mit der schlechtesten Lesbarkeit als die Methode mit der besten Leistung ansah ... es gibt Abstriche bei der Wahl der am besten lesbaren Option ... für die Art von Workloads, für die ich normalerweise Python verwende Wert Lesbarkeit über eine etwas performantere Option, aber wie üblich kommt es darauf an.

0
kinzleb

und mit pure python - keine Bibliotheken importieren

[x for x in  x.split('[')[1].split(']')[0].split('"')[1:-1] if x not in[',',' , ',', ']]
0
Ioannis Nasios

sie können sich das .strip () fcn sparen, indem Sie einfach das erste und das letzte Zeichen aus der String-Darstellung der Liste entfernen (siehe dritte Zeile unten).

>>> mylist=[1,2,3,4,5,'baloney','alfalfa']
>>> strlist=str(mylist)
['1', ' 2', ' 3', ' 4', ' 5', " 'baloney'", " 'alfalfa'"]
>>> mylistfromstring=(strlist[1:-1].split(', '))
>>> mylistfromstring[3]
'4'
>>> for entry in mylistfromstring:
...     print(entry)
...     type(entry)
... 
1
<class 'str'>
2
<class 'str'>
3
<class 'str'>
4
<class 'str'>
5
<class 'str'>
'baloney'
<class 'str'>
'alfalfa'
<class 'str'>
0
JCMontalbano