2010-03-21 21 views
23

He estado buscando intentando encontrar una respuesta a esta pregunta, y parece que no puedo encontrarla. Quizás es demasiado tarde en la noche para descifrar la respuesta, así que me dirijo a los excelentes lectores de aquí.Convirtiendo JSON en el dict de Python

tengo el siguiente bit de datos JSON que estoy tirando de un registro CouchDB:

"{\"description\":\"fdsafsa\",\"order\":\"1\",\"place\":\"22 Plainsman Rd, Mississauga, ON, Canada\",\"lat\":43.5969175,\"lng\":-79.7248744,\"locationDate\":\"03/24/2010\"},{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"}," 

Estos datos se almacenan en el interior de un diccionario de Python en la clave 'locations' en un diccionario llamado 'my_plan' . Quiero para convertir estos datos de CouchDB en un diccionario de Python para que pueda hacer lo siguiente en una plantilla de Django: un montón

{% for location in my_plan.locations %}               
<tr> 
    <td>{{ location.place }}</td> 
    <td>{{ location.locationDate }}</td> 
</tr> 

{% endfor %} 

que he encontrado de información sobre la conversión de dicts a JSON, pero nada de volver al otro camino.

Respuesta

18

La cadena que espectáculo no es un objeto JSON con códigos (eq a un diccionario de Python) - más como una matriz (eq a una lista) sin paréntesis y con una coma adicional perdida al final. Así que (utilizando simplejson para la versión portabilidad - de json la biblioteca estándar de 2,6 está muy bien también, por supuesto! -):

>>> import simplejson 
>>> js = "{\"description\":\"fdsafsa\",\"order\":\"1\",\"place\":\"22 Plainsman Rd, Mississauga, ON, Canada\",\"lat\":43.5969175,\"lng\":-79.7248744,\"locationDate\":\"03/24/2010\"},{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"}," 
>>> simplejson.loads('[%s]' % js[:-1]) 
[{'description': 'fdsafsa', 'order': '1', 'place': '22 Plainsman Rd, Mississauga, ON, Canada', 'lat': 43.596917500000004, 'lng': -79.724874400000004, 'locationDate': '03/24/2010'}, {'description': 'sadfdsa', 'order': '2', 'place': '50 Dawnridge Trail, Brampton, ON, Canada', 'lat': 43.730477399999998, 'lng': -79.805543499999999, 'locationDate': '03/26/2010'}] 

Si realmente quiere un diccionario que tendrá que especificar cómo tratar a estos dos elementos no identificados, es decir, ¿qué teclas arbitrarias quieres darles? ...?

+1

Tu solución funcionó a la perfección. ¡Gracias! Arreglaré la rutina que * genera * esos datos antes de que entren en CouchDB para no agregar esa coma adicional. Un poco de descuido en la codificación de la noche – GrumpyCanuck

+1

@Grumpy, claro, si yo fuera tú, también pondría los corchetes alrededor de la cadena en el DB, solo para asegurarme de que es JSON válido en vez de "JSON algo incompleto" que el el código de recepción debe completarse. –

+1

Estaba haciendo eso antes, pero no puedo recordar por qué * paré * hacerlo ... la codificación tarde en la noche requiere notas a partir de ahora Creo que – GrumpyCanuck

2
django.utils.simplejson.loads(someJson) 
+1

no se convierte en un diccionario. Lo intenté;) – GrumpyCanuck

+0

El error real que da es "Datos adicionales: línea 1 columna 151 - línea 1 columna 304 (caracteres 151 - 304)" – GrumpyCanuck

+1

Entonces no tiene JSON. –

37
  • Utilice el módulo json para cargar JSON. (Pre-2.6 utiliza el tercer módulo del partido simplejson, que tiene la misma API exacta.)

    >>> import json 
    >>> s = '{"foo": 6, "bar": [1, 2, 3]}' 
    >>> d = json.loads(s) 
    >>> print d 
    {u'foo': 6, u'bar': [1, 2, 3]} 
    
  • Sus datos reales no se pueden cargar esta manera, ya que es en realidad dos objetos JSON separadas por una coma y con una coma final . Tendrá que separarlos o tratar con esto.

    • ¿De dónde sacaste esta cuerda?
+0

Esa cadena proviene de los datos generados por una aplicación en la que estoy trabajando, una especie de aplicación social de ubicación y fecha para personas que planean viajes, recorridos de bares, etc. – GrumpyCanuck

0

Primera cosa primera.

Aquí he guardado su sacó cadena de datos en una variable llamada data_str que tiene dos diccionarios.

>>> data_str = "{\"description\":\"fdsafsa\",\"order\":\"1\",\"place\":\"22 Plainsman Rd, Mississauga, ON, Canada\",\"lat\":43.5969175,\"lng\":-79.7248744,\"locationDate\":\"03/24/2010\"},{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"}," 

Después de eso me convierte en otra cadena denominada data_str2 que está en lista forma y eliminado coma adicional (,) del extremo (ya que da error mientras que los datos de cadena a pitón objeto conversión).

>>> data_str2 = "[" + data_str[0: 1] + data_str[1: len(data_str)-1] + "]" 

Por último, convertí este lista de cadenas (una lista que tiene 2 diccionarios) en la lista original de Python y se almacenan en una variable llamada DATA_LIST.

>>> import json 
>>> data_list = json.loads(data_str2) # Now data_list is a list having 2 dictionaries 

Ahora imprimiremos nuestros datos.

>>> print data_list 
[{u'description': u'fdsafsa', u'order': u'1', u'place': u'22 Plainsman Rd, Mississauga, ON, Canada', u'lat': 43.5969175, u'lng': -79.7248744, u'locationDate': u'03/24/2010'}, {u'description': u'sadfdsa', u'order': u'2', u'place': u'50 Dawnridge Trail, Brampton, ON, Canada', u'lat': 43.7304774, u'lng': -79.8055435, u'locationDate': u'03/26/2010'}] 
>>> 
>>> print type(data_list) 
<type 'list'> 
>>> 
>>> print data_list[0] 
{u'description': u'fdsafsa', u'order': u'1', u'place': u'22 Plainsman Rd, Mississauga, ON, Canada', u'lat': 43.5969175, u'lng': -79.7248744, u'locationDate': u'03/24/2010'} 
>>> 
>>> print data_list[1] 
{u'description': u'sadfdsa', u'order': u'2', u'place': u'50 Dawnridge Trail, Brampton, ON, Canada', u'lat': 43.7304774, u'lng': -79.8055435, u'locationDate': u'03/26/2010'} 
>>> 

pasar esta DATA_LIST lista de puntos de vista y acceder a ella en su plantillas de Django de la siguiente manera, el segmento de código

{% for data in locations %} 
     <tr> 
      <td> {{ data.place }} </td> 
      <td> {{ data.locationDate }} </td> 
     </tr> 
{% endfor %} 

Una muestra de sus puntos de vista.

def locations(request): 
    # YOU HAVE TO WRITE YOUR CODE LOGIC HERE TO GET THE LIST, 
    # I AM WRITING IT DIRECTLY 
    data_list = [{u'description': u'fdsafsa', u'order': u'1', u'place': u'22 Plainsman Rd, Mississauga, ON, Canada', u'lat': 43.5969175, u'lng': -79.7248744, u'locationDate': u'03/24/2010'}, {u'description': u'sadfdsa', u'order': u'2', u'place': u'50 Dawnridge Trail, Brampton, ON, Canada', u'lat': 43.7304774, u'lng': -79.8055435, u'locationDate': u'03/26/2010'}] 
    return render(request, "locations.html", {"locations": data_list}) 

IT WORKED NICE.

ahora quiero explicar que la forma en que llegué a solución, creo que va a ser útil para los principiantes. Consulte el procedimiento explicado a continuación paso a paso o see here.

>>> import json 
>>> 
>>> # A simple attempt 
>>> s = "{\"description\":\"fdsafsa\"}" 
>>> python_dict = json.loads(s) 
>>> python_dict 
{u'description': u'fdsafsa'} 
>>> # Accessing value using key 
>>> python_dict["description"] 
u'fdsafsa' 
>>> 
>>> # It worked, lets test our given string containing 2 dictionaries(in string form) one by one 
>>> # Converting 1st JSON string to Dict 
>>> s2 = "{\"description\":\"fdsafsa\",\"order\":\"1\",\"place\":\"22 Plainsman Rd, Mississauga, ON, Canada\",\"lat\":43.5969175,\"lng\":-79.7248744,\"locationDate\":\"03/24/2010\"}" 
>>> python_dict2 = json.loads(s2)                      >>> python_dict2 
{u'description': u'fdsafsa', u'order': u'1', u'place': u'22 Plainsman Rd, Mississauga, ON, Canada', u'lat': 43.5969175, u'lng': -79.7248744, u'locationDate': u'03/24/2010'} 
>>> 
>>> # Converting 2nd JSON string to Dict 
>>> # remove comma(,) from end otherwise you will get the following error 
>>> s3 = "{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"}," 
>>> python_dict3 = json.loads(s3) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 339, in loads 
    return _default_decoder.decode(s) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 367, in decode 
    raise ValueError(errmsg("Extra data", s, end, len(s))) 
ValueError: Extra data: line 1 column 152 - line 1 column 153 (char 151 - 152) 
>>> 
>>> # Now I removed comma(,) from end and retried, it worked 
>>> s3 = "{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"}" 
>>> python_dict3 = json.loads(s3) 
>>> 
>>> # So now we knew that we have not to include any extra comma at end in the string form of JSON 
>>> # For example (Correct form) 
>>> details_str = "{\"name\":\"Rishikesh Agrawani\", \"age\": 25}" 
>>> details_dict = json.loads(details_str) 
>>> details_dict["name"] 
u'Rishikesh Agrawani' 
>>> details_dict["age"] 
25 
>>> # Now (Incorrect form), here comma(,) is at end, just after } 
>>> details_str = "{\"name\":\"Rishikesh Agrawani\", \"age\": 25}," 
>>> details_dict = json.loads(details_str) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 339, in loads 
    return _default_decoder.decode(s) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 367, in decode 
    raise ValueError(errmsg("Extra data", s, end, len(s))) 
ValueError: Extra data: line 1 column 41 - line 1 column 42 (char 40 - 41) 
>>> 
>>> # The problem is the string does not denote any single python object 
>>> # So we will convert the string into a list form by appending [ at beginning and ] at end 
>>> # Now our string will denote a single Pytohn object that is list of 2 dictioanaries 
>>> # Lets do this, here I am storing the given string into variable s4 
>>> data_str = "{\"description\":\"fdsafsa\",\"order\":\"1\",\"place\":\"22 Plainsman Rd, Mississauga, ON, Canada\",\"lat\":43.5969175,\"lng\":-79.7248744,\"locationDate\":\"03/24/2010\"},{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"}," 
>>> s5 = "[" + s4[0:1] + s4[1: len(s4)-1] + "]" 
>>> s5 
'[{"description":"fdsafsa","order":"1","place":"22 Plainsman Rd, Mississauga, ON, Canada","lat":43.5969175,"lng":-79.7248744,"locationDate":"03/24/2010"},{"description":"sadfdsa","order":"2","place":"50 Dawnridge Trail, Brampton, ON, Canada","lat":43.7304774,"lng":-79.8055435,"locationDate":"03/26/2010"}]' 
>>> # l is a list of 2 dictionaries 
>>> l = json.loads(s5) 
>>> l[0] 
{u'description': u'fdsafsa', u'order': u'1', u'place': u'22 Plainsman Rd, Mississauga, ON, Canada', u'lat': 43.5969175, u'lng': -79.7248744, u'locationDate': u'03/24/2010'} 
>>> 
>>> l[1] 
{u'description': u'sadfdsa', u'order': u'2', u'place': u'50 Dawnridge Trail, Brampton, ON, Canada', u'lat': 43.7304774, u'lng': -79.8055435, u'locationDate': u'03/26/2010'} 
>>>               

Gracias.

0
Hello here my example 
import json 
class SimpleObject(object): 
    def __init__(self, _dict): 
     self.__dict__.update(_dict) 

data=json.loads("{\"name\":\"Rishikesh Agrawani\", \"age\": 25}") 
so=SimpleObject(data) 
print (so.name) 
print (so.age) 

if you transform your data to objects is better and more fast work. 
0

Sólo una combinación de otras respuestas:

import json 
yourString = "{\"description\":\"fdsafsa\",\"order\":\"1\",\"place\":\"22 Plainsman Rd, Mississauga, ON, Canada\",\"lat\":43.5969175,\"lng\":-79.7248744,\"locationDate\":\"03/24/2010\"},{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"}," 
target = json.loads("[" + yourString[:-1] + "]") 

salidas

[{u'description': u'fdsafsa', u'order': u'1', u'place': u'22 Plainsman Rd, Mississauga, ON, Canada', u'lat': 43.5969175, u'lng': -79.7248744, u'locationDate': u'03/24/2010'}, {u'description': u'sadfdsa', u'order': u'2', u'place': u'50 Dawnridge Trail, Brampton, ON, Canada', u'lat': 43.7304774, u'lng': -79.8055435, u'locationDate': u'03/26/2010'}] 

Como se mencionó

  • esta cadena contiene dos objetos JSON, por lo que puso dentro de una matriz ([])
  • que al final tiene una ,, eliminar a través de la sintaxis de rebanado [:-1]
Cuestiones relacionadas