Question

I am trying to access an element of a python list, after I do a line by line JSON object parsing, I can't access the values.

For example:

data1 = [{u'time': 136.648, u'name': u'machine', u'value': 71.3}];
data1 = str(data1)[1:-1]
print data1
print data1 ['time']

Grabbing the 'time' value from data1 gives an error:

TypeError: string indices must be integers, not str
{u'name': u'machine', u'value': 71.3, u'time': 136.648}

Alternatively the following works correctly:

data2 = '{"time": 136.648, "name": "machine", "value":71.3}'
data2 = json.loads(data2)
print data2
print data2 ['time']

Output:

{u'name': u'machine', u'value': 71.3, u'time': 136.648}
136.648

Why does one work and the other not? Both data1 and data2 seem to be the same thing.

I want to parse this list such that I can access the data inside of it:

data = [{u'time': 136.648, u'name': u'machine', u'value': 71.3}, {u'time': 138.648, u'name': u'machine2', u'value': 71.56}];
Was it helpful?

Solution

In the first case, you have the string "{u'name': u'machine', u'value': 71.3, u'time': 136.648}". This is not a dictionary - it is a string. You're trying to access a string key of a string, but strings don't have string keys, they only have integer indices.

In the second case, you parse the string (via JSON) and you get a dictionary, which you then access.

Perhaps this will help:

>>> a = [{u'time': 136.648, u'name': u'machine', u'value': 71.3}]
>>> b = str(a)[1:-1]
>>> c = '{"time": 136.648, "name": "machine", "value":71.3}'
>>> d = json.loads(c)

>>> a
[{u'name': u'machine', u'value': 71.3, u'time': 136.648}]
>>> type(a)
<type 'list'>
>>> a[0]
{u'name': u'machine', u'value': 71.3, u'time': 136.648}
>>> a[0]['time']
136.648

>>> b
"{u'name': u'machine', u'value': 71.3, u'time': 136.648}"
>>> type(b)
<type 'str'>
>>> b[0]
'{'
>>> b['time']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string indices must be integers, not str

>>> c
'{"time": 136.648, "name": "machine", "value":71.3}'
>>> type(c)
<type 'str'>
>>> c[0]
'{'
>>> c['time']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string indices must be integers, not str

>>> d
{u'name': u'machine', u'value': 71.3, u'time': 136.648}
>>> type(d)
<type 'dict'>
>>> d['time']
136.648

OTHER TIPS

When you do this:

data1 = [{u'time': 136.648, u'name': u'machine', u'value': 71.3}];
data1 = str(data1)[1:-1]
print data1 # string
print type(data1)     # => prints out <type 'str'>
print data1 ['time']  # accessing a string without an index doesn't work

You are attempting to access an index of a string.

The following works because you've loaded the data which as a string is legitimate json:

data2 = '{"time": 136.648, "name": "machine", "value":71.3}'
data2 = json.loads(data2)
print data2
print type(data2) # => prints out <type 'dict'>
print data2 ['time']

Why data1 doesn't work:

data2 works because it's a dict, and data1 is a string and doesn't work because you can't access strings with anything but a numeric index or slice.

In the first case you have a list of dictionaries: get rid of data1= str(data1)[1:-1] and use print data1[0]['time'].

this code found on stackoverflow should decode this string for you (Fastest way to convert a dict's keys & values from `unicode` to `str`?)

ATA = { u'spam': u'eggs', u'foo': frozenset([u'Gah!']), u'bar': { u'baz': 97 },
     u'list': [u'list', (True, u'Maybe'), set([u'and', u'a', u'set', 1])]}

def convert(data):
    if isinstance(data, basestring):
        return str(data)
    elif isinstance(data, collections.Mapping):
        return dict(map(convert, data.iteritems()))
    elif isinstance(data, collections.Iterable):
        return type(data)(map(convert, data))
    else:
        return data

print DATA
print convert(DATA)
# Prints:
# {u'list': [u'list', (True, u'Maybe'), set([u'and', u'a', u'set', 1])], u'foo': frozenset([u'Gah!']), u'bar': {u'baz': 97}, u'spam': u'eggs'}
# {'bar': {'baz': 97}, 'foo': frozenset(['Gah!']), 'list': ['list', (True, 'Maybe'), set(['and', 'a', 'set', 1])], 'spam': 'eggs'}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top