Domanda Converti la rappresentazione della stringa di lista in lista


Mi stavo chiedendo quale sia il modo più semplice per convertire un string elencare come segue in a list:

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

Anche nel caso in cui l'utente inserisca degli spazi tra le virgole e gli spazi all'interno delle virgolette. Devo occuparmi anche di:

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

in Python.

So di poter spogliare gli spazi con strip() e split() utilizzando l'operatore di divisione e verifica la presenza di caratteri non alfabetici. Ma il codice stava diventando molto sfacciato. C'è una funzione rapida di cui non sono a conoscenza?


279
2017-12-12 18:19


origine


risposte:


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

Con ast.literal_eval, è possibile valutare in sicurezza un nodo di espressione o una stringa contenente un'espressione Python. La stringa o il nodo fornito possono consistere solo delle seguenti strutture letterali Python: stringhe, numeri, tuple, liste, dict, booleani e Nessuno.


461
2017-12-12 18:30



Il eval è pericoloso - non dovresti eseguire l'input dell'utente.

Se hai 2.6 o più recenti, usa ast invece di eval:

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

Una volta che lo hai, strip le stringhe.

Se sei su una versione precedente di Python, puoi avvicinarti molto a ciò che vuoi con una semplice espressione regolare:

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

Questo non è buono come la soluzione ast, ad esempio non gestisce correttamente le virgolette di escape nelle stringhe. Ma è semplice, non comporta una valutazione pericolosa, e potrebbe essere abbastanza buono per il tuo scopo se sei su un Python più vecchio senza ast.


59
2017-12-12 18:29



Il json il modulo è una soluzione migliore ogni volta che c'è un stringata elenco di dizionari. Il json.loads(your_data) la funzione può essere utilizzata per convertirla in una lista.

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

allo stesso modo

>>> x = u'[ "A","B","C" , {"D":"E"}]'
>>> json.loads(x)
[u'A', u'B', u'C', {u'D': u'E'}]

39
2018-02-17 15:39



import ast
l = ast.literal_eval('[ "A","B","C" , " D"]')
l = [i.strip() for i in l]

9
2017-12-12 18:29



con numpy questo sta funzionando in un modo molto semplice

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

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

8
2017-11-01 10:12



Supponendo che tutti i tuoi input siano elenchi e che le virgolette nell'input non contengano, questo può essere fatto con una semplice regexp replace. È un po 'perl-y ma funziona come un fascino. Si noti inoltre che l'output è ora un elenco di stringhe Unicode, non è stato specificato che è necessario, ma sembra avere un senso dato input Unicode.

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

La variabile junkers contiene un regexp compilato (per la velocità) di tutti i caratteri che non vogliamo, usando] come carattere richiesto qualche trucco di barra retroversa. Il re.sub sostituisce tutti questi caratteri con niente e dividiamo la stringa risultante con le virgole.

Nota che questo rimuove anche gli spazi dalle voci interne u '["oh no"]' ---> [u'ohno ']. Se questo non è ciò che volevi, la regexp deve essere un po 'truccata.


7
2017-12-12 22:18



C'è una soluzione rapida:

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

Gli spazi vuoti indesiderati negli elementi della lista possono essere rimossi in questo modo:

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

6
2017-12-12 18:24



Se sai che i tuoi elenchi contengono solo stringhe tra virgolette, questo esempio di pypars ti darà l'elenco delle stringhe spogliate (anche conservando l'originale 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']

Se le tue liste possono avere più tipi di dati, o persino contenere liste all'interno di elenchi, allora avrai bisogno di una grammatica più completa questo sul wiki di pyparsing, che gestirà tuple, liste, interi, float e stringhe tra virgolette. Funzionerà con le versioni di Python fino a 2.4.


3
2017-12-12 21:38



Per completare ulteriormente la risposta di @Ryan usando json, una funzione molto conveniente per convertire unicode è quella pubblicata qui: https://stackoverflow.com/a/13105359/7599285

ex con virgolette doppie o singole:

>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
2018-04-27 13:56



Vorrei fornire una soluzione di disegno più intuitiva con regex. La funzione seguente prende come input un elenco con stringhe contenenti stringhe arbitrarie.

Spiegazione graduale: Rimuovete tutti gli spazi bianchi, bracketing e value_separators (a condizione che non facciano parte dei valori che volete estrarre, altrimenti rendete l'espressione regex più complessa). Quindi dividi la stringa pulita su virgolette singole o doppie e prendi i valori non vuoti (o valori indicizzati dispari, qualunque sia la preferenza).

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
2018-06-01 09:32