Eu queria saber qual é a maneira mais simples de converter uma string
lista como a seguinte em um list
:
x = u'[ "A","B","C" , " D"]'
Mesmo que o usuário coloque espaços entre as vírgulas e espaços dentro das aspas. Eu preciso lidar com isso também para:
x = ["A", "B", "C", "D"]
em Python.
Sei que posso retirar espaços com strip()
e split()
usando o operador split e verificar se não há alfabetos. Mas o código estava ficando muito desajeitado. Existe uma função rápida que eu não conheço?
Respostas:
ast.literal_eval :
fonte
eval
, nãoast.literal_eval
.ast.literal_eval
é mais seguro queeval
, mas na verdade não é seguro . Como as versões recentes dos documentos explicam: "Aviso É possível travar o interpretador Python com uma sequência suficientemente grande / complexa devido às limitações de profundidade da pilha no compilador AST do Python." De fato, pode ser possível executar código arbitrário por meio de um cuidadoso ataque de quebra de pilha, embora, até onde eu saiba, ninguém construa uma prova pública de conceito para isso.O
json
módulo é uma solução melhor sempre que houver uma lista estrita de dicionários. Ajson.loads(your_data)
função pode ser usada para convertê-lo em uma lista.similarmente
fonte
'["a","b"]'
mas não para"['a','b']"
.A
eval
é perigoso - você não deve executar a entrada do usuário.Se você possui 2.6 ou mais recente, use ast em vez de eval:
Depois de ter isso,
strip
as cordas.Se você está em uma versão mais antiga do Python, pode se aproximar muito do que deseja com uma simples expressão regular:
Isso não é tão bom quanto a solução ast, por exemplo, ele não lida corretamente com aspas escapadas em strings. Mas é simples, não envolve uma avaliação perigosa e pode ser suficiente para o seu objetivo se você estiver em um Python mais antigo sem ast.
fonte
eval
É perigoso - você não deve executar a entrada do usuário". Eu estou usando 3.6eval
diretamente, ele avaliará qualquer expressão python válida, o que é potencialmente perigoso.literal_eval
resolve esse problema avaliando apenas estruturas literais do Python: seqüências de caracteres, números, tuplas, listas, dictos, booleanos e Nenhum.fonte
Existe uma solução rápida:
Os espaços em branco indesejados nos elementos da lista podem ser removidos desta maneira:
fonte
Inspirado em algumas das respostas acima que funcionam com pacotes python básicos, comparei o desempenho de alguns (usando o Python 3.7.3):
Método 1: ast
Método 2: json
Método 3: sem importação
Fiquei desapontado ao ver o que considerava o método com a pior legibilidade, o método com o melhor desempenho ... existem trocas a serem consideradas ao escolher a opção mais legível ... para o tipo de carga de trabalho que eu uso python normalmente legibilidade do valor sobre uma opção um pouco mais eficiente, mas, como sempre, depende.
fonte
Se for apenas uma lista unidimensional, isso pode ser feito sem importar nada:
fonte
Supondo que todas as suas entradas sejam listas e que as aspas duplas na entrada realmente não importam, isso pode ser feito com uma simples substituição de regexp. É um pouco pervertido, mas funciona como um encanto. Observe também que a saída agora é uma lista de cadeias unicode, você não especificou que precisava disso, mas parece fazer sentido dada a entrada unicode.
A variável junkers contém um regexp compilado (para velocidade) de todos os caracteres que não queremos, usando] como um caractere necessário alguns truques de barra invertida. O re.sub substitui todos esses caracteres por nada e dividimos a sequência resultante pelas vírgulas.
Observe que isso também remove espaços das entradas internas u '["oh não"]' ---> [u'ohno ']. Se não é o que você queria, o regexp precisa ser aprimorado um pouco.
fonte
Se você souber que suas listas contêm apenas seqüências de caracteres entre aspas, este exemplo de pyparsing fornecerá sua lista de cadeias de caracteres com strip (mesmo preservando o Unicode-ness original).
Se suas listas podem ter mais tipos de dados ou até mesmo listas dentro de listas, você precisará de uma gramática mais completa - como esta no wiki pyparsing, que lida com tuplas, listas, ints, flutuadores e seqüências de caracteres citadas. Trabalhará com versões do Python de volta para 2.4.
fonte
parsePythonValue.py
exemplo agora está no GitHub em github.com/pyparsing/pyparsing/blob/master/examples/…Para completar ainda mais a resposta de @Ryan usando json, uma função muito conveniente para converter unicode é a postada aqui: https://stackoverflow.com/a/13105359/7599285
ex com aspas duplas ou simples:
fonte
Eu gostaria de fornecer uma solução de padrões mais intuitiva com o regex. A função abaixo usa como entrada uma lista estratificada contendo seqüências arbitrárias.
Explicação passo a passo: Você remove todos os espaços em branco, bracketing e value_separators (desde que eles não façam parte dos valores que você deseja extrair, caso contrário, torne o regex mais complexo). Em seguida, divida a sequência limpa entre aspas simples ou duplas e obtenha os valores não vazios (ou valores indexados ímpares, independentemente da preferência).
testample : "['21'," foo "'6', '0'," A "]"
fonte
e com python puro - não importando nenhuma biblioteca
fonte
Você pode encontrar esse problema ao lidar com dados raspados armazenados como Pandas DataFrame.
Essa solução funciona como charme se a lista de valores estiver presente como texto .
fonte
Então, seguindo todas as respostas, decidi cronometrar os métodos mais comuns:
Então, no final, o regex vence!
fonte
você pode salvar o arquivo .strip () fcn cortando apenas o primeiro e o último caracteres da representação de string da lista (veja a terceira linha abaixo)
fonte