¿Cómo convertir un diccionario a una cadena de consulta en Python?
112
Después de usar cgi.parse_qs(), ¿cómo convertir el resultado (diccionario) de nuevo a una cadena de consulta? Buscando algo similar a urllib.urlencode().
Convierta un objeto de mapeo o una secuencia de tuplas de dos elementos, que pueden contener objetos str o bytes, en una cadena de texto ASCII codificada en porcentaje.
urllib.urlencode( query[, doseq])
Convertir un objeto de mapeo o una secuencia de tuplas de dos elementos en una cadena de "porcentaje codificado" ... una serie de key=valuepares separados por '&'caracteres ...
Esto es cierto, pero el dictdevuelto por en cgi.parse_qs()realidad tiene lists como sus "valores". Pasar estos directamente dará como resultado cadenas de consulta de aspecto muy extraño.
Johnsyweb
Suficientemente cierto. ¡Eso me enseñará a leer más que la primera oración!
¡Estás buscando algo exactamente igual urllib.urlencode()!
Sin embargo, cuando llama parse_qs()(distinto de parse_qsl()), las claves del diccionario son los nombres únicos de las variables de consulta y los valores son listas de valores para cada nombre.
Para pasar esta información urllib.urlencode(), debe "aplanar" estas listas. Así es como puede hacerlo con una lista de comprensión de tuplas:
query_pairs =[(k,v)for k,vlist in d.iteritems()for v in vlist]
urllib.urlencode(query_pairs)
Toma un diccionario y lo convierte en una cadena de consulta, como urlencode. Agregará un "&" final a la cadena de consulta, pero lo return query[:-1]corrige si es un problema.
¿Ya te conociste str.join()? ¿Qué tal urllib.quote_plus()?
Ignacio Vazquez-Abrams
1
@garbados Su solución debería funcionar en casos simples. Sin embargo, tener una mirada urlencodeen urllib.py(debe por su pitón en la instalación) para ver qué crear una cadena de consulta a veces no es tan simple como su respuesta implica (en particular, la necesidad de 'cita' ciertos caracteres que no son válidos en una URL). @Ignacio también ha hecho referencia a dos funciones que limpiarían su implementación y la corregirían.
Anthony Cramp
Ah, en verdad. Perdón por la mala implementación. Va a demostrar que debería ser más cuidadoso al responder preguntas a las que nunca me he enfrentado.
garbados
Si bien esta puede no ser la mejor respuesta, es exactamente lo que quería ver cuando hice clic en el título de esta pregunta. Solo tengo 4 elementos en un dictado que necesito convertir en un par nombre = valor separados por un '&'. Mis valores están controlados. El str.join () es útil en mi caso, pero no necesito quote_plus (), nuevamente, porque no es un código público :) ¡Gracias!
harperville
1
@harperville, ¡pero la forma más correcta ( from urllib.parse import urlencode; urlencode(your_dict)) es más corta y más fácil que esta! Reconozco que a veces es inteligente reinventar la rueda, incluso aunque sea de mala calidad, cuando es caro o inconveniente acceder a las ruedas existentes y bien diseñadas, pero aquí usar la rueda estándar es más fácil y rápido que hacer rodar una rueda inferior. .
cgi.parse_qs()
está en desuso. Utilice urlparse.parse_qs () en su lugar.Respuestas:
Python 3
A
dict
es un mapeo.Python heredado
fuente
dict
devuelto por encgi.parse_qs()
realidad tienelist
s como sus "valores". Pasar estos directamente dará como resultado cadenas de consulta de aspecto muy extraño.En python3, ligeramente diferente:
salida:
'pram1=foo¶m2=bar'
para compatibilidad con python2 y python3, intente esto:
fuente
¡Estás buscando algo exactamente igual
urllib.urlencode()
!Sin embargo, cuando llama
parse_qs()
(distinto deparse_qsl()
), las claves del diccionario son los nombres únicos de las variables de consulta y los valores son listas de valores para cada nombre.Para pasar esta información
urllib.urlencode()
, debe "aplanar" estas listas. Así es como puede hacerlo con una lista de comprensión de tuplas:fuente
doseq=True
.Quizás estés buscando algo como esto:
Toma un diccionario y lo convierte en una cadena de consulta, como urlencode. Agregará un "&" final a la cadena de consulta, pero lo
return query[:-1]
corrige si es un problema.fuente
str.join()
? ¿Qué talurllib.quote_plus()
?urlencode
enurllib.py
(debe por su pitón en la instalación) para ver qué crear una cadena de consulta a veces no es tan simple como su respuesta implica (en particular, la necesidad de 'cita' ciertos caracteres que no son válidos en una URL). @Ignacio también ha hecho referencia a dos funciones que limpiarían su implementación y la corregirían.from urllib.parse import urlencode; urlencode(your_dict)
) es más corta y más fácil que esta! Reconozco que a veces es inteligente reinventar la rueda, incluso aunque sea de mala calidad, cuando es caro o inconveniente acceder a las ruedas existentes y bien diseñadas, pero aquí usar la rueda estándar es más fácil y rápido que hacer rodar una rueda inferior. .