0

I have an array of dictionaries but i am running into a scenario where I have to get the value from 1st index of the array of dictionaries, following is the chunk that I am trying to query.

address_data = record.get('Rdata')[0].get('Adata')

This throws the following error:

TypeError: 'NoneType' object is not subscriptable

I tried following:

if record.get('Rdata') and record.get('Rdata')[0].get('Adata'):
   address_data = record.get('Rdata')[0].get('Adata')

but I don't know if the above approach is good or not.

So how to handle this in python?

Edit:

"partyrecord": {

      "Rdata": [
        {

          "Adata": [
            {
              "partyaddressid": 172,
              "addressid": 142165
            }
          ]

        }
      ]
    }
noobie-php
  • 6,817
  • 15
  • 54
  • 101
  • 3
    Can you give an example of what `address_data` looks like? – TheStrangeQuark Apr 04 '19 at 19:03
  • This may help: https://stackoverflow.com/questions/31033549/nested-dictionary-value-from-key-path – rdas Apr 04 '19 at 19:04
  • 1
    You can one-line this: `address_data = bool(record.get('Rdata')) and record.get('Rdata')[0].get('Adata') or None` - you can replace `None` with whatever fallback value you want – JacobIRR Apr 04 '19 at 19:05
  • 1
    We need to see what `record` loops like, not `address_data` – roganjosh Apr 04 '19 at 19:05
  • 1
    @JacobIRR `len(record.get('Rdata'))` immediately fails if the value doesn't exist because it becomes `len(None)` – roganjosh Apr 04 '19 at 19:06
  • `record.get('Rdata')` this is returning `None`. You need to break up this statement to handle that case – Paul H Apr 04 '19 at 19:07
  • @JacobIRR Wouldn't that just return 1 or 0 and not the actual value inside the dict? – alex067 Apr 04 '19 at 19:07
  • @roganjosh , i have posted some sample – noobie-php Apr 04 '19 at 19:09
  • @JacobIRR you've fixed the error, but no need for `bool` now :) `None` is falsey, so just `if record.get('Rdata') and...` but even then, you can return an empty dict if the first lookup fails – roganjosh Apr 04 '19 at 19:09
  • 1
    I see the example but it's disembodied from the problem you describe. There is no `Rdata` key. Please give a [mcve]. The level of nesting for `record` is too deep for your approach to work with that sample. – roganjosh Apr 04 '19 at 19:10
  • @noobie-php, your proposed solution seems ok to me. It avoids the issue mentioned in the comments because `if record.get('Rdata')` checks both for the record 'Rdata' to exist in 'record', and for it to reference a container that has something in it. So you should safely be able to say `record.get('Rdata')[0]` if this test succeeds. (assuming your assumptions about your data are otherwise correct). – CryptoFool Apr 04 '19 at 19:10
  • @noobie-php, ...now, about your data...first of all, I assume you want a pair of curly braces around what you've given us, as what you have here isn't legal Python by itself. what do you want to do exactly with this data? – CryptoFool Apr 04 '19 at 19:12

2 Answers2

4

Your expression assumes that record['Rdata'] will return a list with at least one element, so provide one if that isn't the case.

address_data = record.get('Rdata', [{}])[0].get('Adata')

Now if record['Rdata'] doesn't exist, you'll still have an empty dict on which to invoke get('Adata'). The end result will be address_data being set to None.

(Checking for the key first is preferable if a suitable default is expensive to create, since it will be created whether get needs to return it or not. But [{}] is fairly lightweight, and the compiler can generate it immediately.)

chepner
  • 497,756
  • 71
  • 530
  • 681
3

You might want to go for the simple, not exciting route:

role_data = record.get('Rdata')

if role_data:
  address_data = role_data[0].get('Adata')
else:
  address_data = None
Aviv Goldgeier
  • 799
  • 7
  • 23
  • This fails if there is role_data but it isn't an iterable. I guess we can assume it will be – amchugh89 Apr 04 '19 at 19:16
  • 1
    It may be OK to assume that `record` is well-formed, but that `Rdata` is simply optional, rather than accommodating every possible `dict`. (We're also assuming that `record` has a `get` method in the first place.) – chepner Apr 04 '19 at 19:18