¿Cómo convertir un diccionario a una cadena de consulta en Python?


Respuestas:


158

Python 3

urllib.parse.urlencode(consulta, doseq = False, [...])

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.

- Python 3 urllib.parsedocs

A dictes un mapeo.

Python heredado

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

- Python 2.7 urllibdocs


1
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!
Johnsyweb


El problema es que urlencode convertirá el espacio en +, lo cual no se recomienda.
user1633272

1
@ user1633272: ¿No recomendado según quién?
Ignacio Vazquez-Abrams

65

En python3, ligeramente diferente:

from urllib.parse import urlencode
urlencode({'pram1': 'foo', 'param2': 'bar'})

salida: 'pram1=foo&param2=bar'

para compatibilidad con python2 y python3, intente esto:

try:
    #python2
    from urllib import urlencode
except ImportError:
    #python3
    from urllib.parse import urlencode

6

¡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)

15
O podrías pasar doseq=True.
Ignacio Vazquez-Abrams

@downvoter: ¿Cómo podría mejorar esta respuesta? ¡Han pasado seis años desde que lo escribí!
Johnsyweb

-1

Quizás estés buscando algo como esto:

def dictToQuery(d):
  query = ''
  for key in d.keys():
    query += str(key) + '=' + str(d[key]) + "&"
  return query

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.


4
¿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. .
Mark Amery
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.