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