1

Using django-social-auth to grab user data from facebook, it is returning a list of dicts in a unicode string. For example, response.get('education') for a user is returning:

u"[{u'school': {u'id': u'12345', u'name': u'Joe Thiesman High'}, u'type': u'High School'}, {u'school': {u'id': u'23456', u'name': u'Joe Montana University'}, u'type': u'College'}]"

I want to convert this from a string to a list where I can extract the data, but am struggling. An answer to a similar question (String to Dictionary in Python) advised using:

foo=json.loads(string)

but that fails because its a list with nested dicts, 1 for each school, rather than just a dictionary, and it seems to be getting confused. the error im getting is:

ValueError: Extra Data: line 1 column 73 - line 1 column 144

Originally, I was getting a ValueError: Expecting Property Name: line 1, column 2, until I used string.replace() to exchange the " with ', and vice-versa. That did get rid of that error, but I mention in case that wasn't the correct solution.

Community
  • 1
  • 1
gatsby32
  • 45
  • 5
  • It looks like there's a comma missing before u'type': u'College' – adamnfish Jun 03 '11 at 17:05
  • The big problem is that that is not valid JSON. In addition to the fact that it is missing a comma, the contained Strings need to have double-quotes, not single quotes. @See also http://stackoverflow.com/questions/4162642/python-single-vs-double-quotes-in-json – cwallenpoole Jun 03 '11 at 17:11
  • @adamnfish i manually typed it in here and missed that. fixed @cwallenpoole strange, thats the way its being returned from facebook, not sure why its not valid JSON. – gatsby32 Jun 03 '11 at 19:22

3 Answers3

3

Take a look at the answer to this question :

Convert a String representation of a Dictionary to a dictionary?

The use of python's ast.literal_eval might be very useful to you. It is also a lot safer to use than eval because it only will evaluate python data literals (strings, tuples, etc...) but not executable code.

See ast.literal_eval in the python docs.

Community
  • 1
  • 1
mshell_lauren
  • 5,171
  • 4
  • 28
  • 36
1

With a little reformatting you could use something like:

uDictList = eval(inputString)

Probably not the best solution, but might help.

EDIT: Fixed variable name.

knaop
  • 11
  • 1
0

Looks like you have a typo in returned data you provided. It is missing a comma before last u'type'

I am not 100% sure I understand what you are asking but I believe this is the code you are after

retVal = eval(u"[{u'school': {u'id': u'12345', u'name': u'Joe Thiesman High'}, u'type': u'High School'}, {u'school': {u'id': u'23456', u'name': u'Joe Montana University'}, u'type': u'College'}]")

class School:
   def __init__(self):
       self.type = ""
       self.id   = ""
       self.name = ""

   def setType(self, type):
       self.type = type
   def getType(self):
       return self.type

   def setId(self, id):
       self.id= id
   def getId(self):
       return self.id

   def setName(self, name):
       self.name = name
   def getName(self):
       return self.name

class schoolParser:
   def __init__(self, dict):
       self.schoolData = dict
       self.schools=[]
       for i in range(len(self.schoolData)):
           school = School()
           school.setId   ( self.schoolData[i]['school']['id'] )
           school.setName ( self.schoolData[i]['school']['name'] )            
           school.setType ( self.schoolData[i]['type'] )
           self.schools.append(school)

       # Later in the code you get data like this
       for school in self.schools:
           print school.getName(), school.getType(), school.getId()


if __name__ == "__main__" : schoolParser(retVal)
storm_to
  • 1,495
  • 2
  • 16
  • 24