36

I am very new to Python and parsing data.

I can pull an external JSON feed into a Python dictionary and iterate over the dictionary.

for r in results:
     print r['key_name']

As I walk through the results returned, I am getting an error when a key does not have a value (a value may not always exist for a record). If I print the results, it shows as

'key_name': None, 'next_key':.................

My code breaks on the error. How can I control for a key not having a value?

Any help will be greatly appreciated!

Brock

Brandon Rhodes
  • 83,755
  • 16
  • 106
  • 147
Btibert3
  • 38,798
  • 44
  • 129
  • 168

8 Answers8

93

The preferred way, when applicable:

for r in results:
     print r.get('key_name')

this will simply print None if key_name is not a key in the dictionary. You can also have a different default value, just pass it as the second argument:

for r in results:
     print r.get('key_name', 'Missing: key_name')

If you want to do something different than using a default value (say, skip the printing completely when the key is absent), then you need a bit more structure, i.e., either:

for r in results:
    if 'key_name' in r:
        print r['key_name']

or

for r in results:
    try: print r['key_name']
    except KeyError: pass

the second one can be faster (if it's reasonably rare than a key is missing), but the first one appears to be more natural for many people.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • is there a way to get sub keys of a key using get somehow? – brizz Mar 24 '15 at 23:16
  • @brizz, what's a "sub key"? – Alex Martelli Mar 25 '15 at 01:48
  • 2
    say you have a dict, {data:{'moredata':'value','evenmoredata':'anothervalue'}}, .get works for .get('data'), but is there anyway to access .get('data')['moredata'] – brizz Mar 25 '15 at 02:47
  • 2
    @brizz, the expression you just wrote works fine for the very example you gave. For anything more intricate, I recommend asking a separate Q rather than trying to hijack a 5-years old one in a comment thread!-) – Alex Martelli Mar 25 '15 at 02:56
  • 1
    it doesn't if the key doesn't exist. the reason I'm posting here is because it shows up in google search results as one of the top answers.. (the reason I'm using 'get' is the key may or may not exist). apologies if this is not kosher--but search is how I came across this, and know others will too. python IRC had no good answer for .get() sub keys. ill create another question if there isn't a solution. maybe just need to do an if in .get()? – brizz Mar 25 '15 at 03:06
  • 1
    @brizz, post the other question and you'll get the answer -- hiding an answer to a different question deep in a comment thread on a very old other question would be the second worst example of breach of SO etiquette (the very worst being hiding different questions in comments, as you're doing). – Alex Martelli Mar 25 '15 at 03:25
  • @brizz bumping old thread. did you post your question? I have the same situation as yours. can I get a link please – Boyke Ferdinandes Jul 29 '20 at 21:45
6

There are two straightforward ways of reading from Python dict if key might not be present. for example:

dicty = {'A': 'hello', 'B': 'world'}

  1. The pythonic way to access a key-value pair is:

value = dicty.get('C', 'default value')

  1. The non-pythonic way:

value = dicty['C'] if dicty['C'] else 'default value'

  1. even worse:

try: value = dicty['C'] except KeyError as ke: value = 'default value'

aidanmelen
  • 6,194
  • 1
  • 23
  • 24
1

If possible, use the simplejson library for managing JSON data.

Daishiman
  • 804
  • 1
  • 8
  • 14
1

the initial question in this thread is why I wrote the Dictor library, it handles JSON fallback and None values gracefully without needing try/except or If blocks.

Also gives you additional options like ignore upper/lower case,

see,

https://github.com/perfecto25/dictor

perfecto25
  • 772
  • 9
  • 13
0

use has_key() , and that will return true or false

TIMEX
  • 259,804
  • 351
  • 777
  • 1,080
0

[Updated to remove careless mistake]

You could also do something like this:

for r in (row for row in results if 'a' in row):
    print r['a']

This uses a generator expression to pick "rows" out of "results" where "row" includes the key "a".

Here's a little test script:

results = [{'a':True}, {'b':True}, {'a':True}]
for r in (row for row in results if 'a' in row): print r['a']
Parand
  • 102,950
  • 48
  • 151
  • 186
0

You can use the built in function hasattr

key='key_name'
# or loop your keys 

if hasattr(e, key):
  print(e[key])
else:
  print('No key for %s' % key)
Evhz
  • 8,852
  • 9
  • 51
  • 69
0

Taken from https://stackoverflow.com/a/14923509/1265070

id = getattr(myobject, 'id', None)
ozma
  • 1,633
  • 1
  • 20
  • 28