Como converter um dicionário em string de consulta em Python?
112
Depois de usar cgi.parse_qs(), como converter o resultado (dicionário) de volta em string de consulta? Procurando por algo semelhante a urllib.urlencode().
Converta um objeto de mapeamento ou uma sequência de tuplas de dois elementos, que pode conter objetos str ou bytes, em uma string de texto ASCII com codificação percentual.
urllib.urlencode( query[, doseq])
Converta um objeto de mapeamento ou uma sequência de tuplas de dois elementos em uma string "codificada em porcentagem" ... uma série de key=valuepares separados por '&'caracteres ...
Isso é verdade, mas o dictretornado por cgi.parse_qs()realmente tem lists como seus "valores". Passá-los diretamente resultará em strings de consulta de aparência muito estranha.
Johnsyweb de
É verdade. Isso vai me ensinar a ler mais do que a primeira frase!
Você está procurando por algo exatamente igual urllib.urlencode()!
No entanto, quando você chama parse_qs()(diferente de parse_qsl()), as chaves de dicionário são os nomes de variáveis de consulta exclusivos e os valores são listas de valores para cada nome.
Para passar essas informações urllib.urlencode(), você deve "nivelar" essas listas. Aqui está como você pode fazer isso com uma compreensão de lista de tuplas:
query_pairs =[(k,v)for k,vlist in d.iteritems()for v in vlist]
urllib.urlencode(query_pairs)
Ele pega um dicionário e o converte em uma string de consulta, assim como o urlencode. Ele acrescentará um "&" final à string de consulta, mas return query[:-1]corrigirá isso, se for um problema.
Você já se conheceu str.join()? Que tal urllib.quote_plus()?
Ignacio Vazquez-Abrams,
1
@garbados Sua solução deve funcionar em casos simples. No entanto, ter um olhar urlencodeem urllib.py(ele deve por em sua Python instalar) para ver por que a criação de uma cadeia de consulta, por vezes, não é tão simples como a sua resposta implica (em particular a necessidade de 'citação' determinados caracteres que não são válidas em um URL). @Ignacio também fez referência a duas funções que limpariam sua implementação e a tornariam correta.
Anthony Cramp,
Ah, é verdade. Desculpe pela implementação tosca. Isso mostra que devo ser mais cuidadoso ao responder a perguntas que nunca enfrentei.
garbados de
Embora essa possa não ser a melhor resposta, é exatamente o que eu queria ver ao clicar no título desta pergunta. Eu tenho apenas 4 itens em um dicionário que preciso transformar em um par nome = valor separado por um '&'. Meus valores são controlados. O str.join () é útil no meu caso, mas não preciso de quote_plus (), novamente, porque não é um código voltado ao público :) Obrigado!
Harperville
1
@harperville mas a forma mais correta ( from urllib.parse import urlencode; urlencode(your_dict)) é mais curta e fácil do que esta! Admito que às vezes é inteligente reinventar a roda, mesmo de maneira inadequada, quando é caro ou inconveniente acessar as rodas existentes e bem projetadas, mas aqui usar a roda pronta é mais fácil e rápido do que girar a roda inferior .
cgi.parse_qs()
está obsoleto. Use urlparse.parse_qs () ao invés.Respostas:
Python 3
A
dict
é um mapeamento.Python legado
fonte
dict
retornado porcgi.parse_qs()
realmente temlist
s como seus "valores". Passá-los diretamente resultará em strings de consulta de aparência muito estranha.Em python3, ligeiramente diferente:
resultado:
'pram1=foo¶m2=bar'
para compatibilidade com python2 e python3, tente o seguinte:
fonte
Você está procurando por algo exatamente igual
urllib.urlencode()
!No entanto, quando você chama
parse_qs()
(diferente deparse_qsl()
), as chaves de dicionário são os nomes de variáveis de consulta exclusivos e os valores são listas de valores para cada nome.Para passar essas informações
urllib.urlencode()
, você deve "nivelar" essas listas. Aqui está como você pode fazer isso com uma compreensão de lista de tuplas:fonte
doseq=True
.Talvez você esteja procurando algo assim:
Ele pega um dicionário e o converte em uma string de consulta, assim como o urlencode. Ele acrescentará um "&" final à string de consulta, mas
return query[:-1]
corrigirá isso, se for um problema.fonte
str.join()
? Que talurllib.quote_plus()
?urlencode
emurllib.py
(ele deve por em sua Python instalar) para ver por que a criação de uma cadeia de consulta, por vezes, não é tão simples como a sua resposta implica (em particular a necessidade de 'citação' determinados caracteres que não são válidas em um URL). @Ignacio também fez referência a duas funções que limpariam sua implementação e a tornariam correta.from urllib.parse import urlencode; urlencode(your_dict)
) é mais curta e fácil do que esta! Admito que às vezes é inteligente reinventar a roda, mesmo de maneira inadequada, quando é caro ou inconveniente acessar as rodas existentes e bem projetadas, mas aqui usar a roda pronta é mais fácil e rápido do que girar a roda inferior .