Reputation: 103
I have a list of dictionaries converted from JSON but few keys seem to be Unicode which giving me trouble accessing the keys of the dictionary. The list looks like this:
d = [{'location': u'',
'partner_id': '648746',
'partner_is_CSP': 'Y',
'partner_name': 'D4T4 SOLUTIONS PLC',
'partner_programs_tiers': [{'program_name': 'Cloud Service Provider',
'tier_name': 'Gold'}],
'partner_type': 'Direct Reseller; Service Provider',
'sort_value': '60',
'url_to_logo': u'',
'url_to_website': 'https://www.d4t4solutions.com/'},
{'location': {'address_type': 'H',
'city': 'Tirane',
'country': 'ALBANIA',
'geo_latitude': '41.348335',
'geo_longitude': '19.79865',
'phone': u'',
'point_of_contact': u'',
'state': u'',
'street_1': 'RR. E DURRESIT PALL. M.C.INERTE KATI 1 LAPRAKE',
'street_2': u'',
'street_3': u'',
'zip': '1023'},
'partner_id': '649341',
'partner_is_CSP': 'N',
'partner_name': 'COMMUNICATION PROGRESS',
'partner_programs_tiers': '[]',
'partner_type': 'Distribution VAR',
'sort_value': '0',
'url_to_logo': u'',
'url_to_website': 'www.commprog.com'}]
Now, I want to do something like this:
l = [i["location"].get("street_1",None) for i in d]
But I'm getting the following error:
AttributeError: 'Unicode' object has no attribute 'get'
How can I work my way around that Unicode? Thanks a lot for your help.
P.S. list d
contains more dictionaries than shown here and it contains more than just one Unicode. When I iter over the dictionaries, I would like to have None
value for the location key with an empty Unicode value is encountered.
Upvotes: 0
Views: 804
Reputation: 28656
Just modifying your attempt a little, using an empty dict as default.
>>> [(i['location'] or {}).get('street_1') for i in d]
[None, 'RR. E DURRESIT PALL. M.C.INERTE KATI 1 LAPRAKE']
Upvotes: 1
Reputation: 123541
As simple way would be:
for i in d:
location = i['location']
if location:
print(location.get('street_1', 'n/a')) # or whatever you want to do...
Upvotes: 0
Reputation: 96287
You could use this (rather unreadable) one-liner:
>>> [r['location'].get('street_1', None) if isinstance(r['location'], dict) else (r['location'] or None) for r in d]
[None, 'RR. E DURRESIT PALL. M.C.INERTE KATI 1 LAPRAKE']
It's probably better to go with a full for-loop:
>>> l = []
>>> for r in d:
... loc = r['location']
... if isinstance(loc, dict):
... l.append(loc.get('street_1', None))
... else:
... l.append(loc or None)
...
>>> l
[None, 'RR. E DURRESIT PALL. M.C.INERTE KATI 1 LAPRAKE']
>>>
Essentially, use isinstance
to check if you are working with a dict
or not. If we are, use .get
, if we aren't, append the value. I use loc or None
which will evalute to None
if loc
is not truthy, which u""
happens to be not truthy.
The alternative is a EAFP approach:
>>> for r in d:
... loc = r['location']
... try:
... l.append(loc.get('street_1', None))
... except AttributeError:
... l.append(loc or None)
...
>>> l
[None, 'RR. E DURRESIT PALL. M.C.INERTE KATI 1 LAPRAKE']
Whether or not it is more efficient to go with that or a LBYL approach depends on the nature of the data. If the "exception" is not truly exceptional, i.e. it occurs frequently, then a LBYL approach will actually be faster, even if EAFP is considered Pythonic.
Upvotes: 2