0

I have inherited Python code which I don't fully understand yet. Here is a structured list which needs only values from the Alternatives key to be returned by a function. The data is like:

{
 'Response': 
[
 {
  'SavingsMessage': '', 
  'SavingNotification': 
  [
   {'AuthorizationNumber': '12345' 'Alternatives': []},
   {'AuthorizationNumber': '6666', 'Alternatives': [{'NDC': '99999'} ]
  ]
}

Above data is in a nested_value variable and is passed to a function in such format:

 level_two = get_nested_value_IRFAN([nested_value,*schema[key][level_one_key][level_one_key]])

while the values of the *schema[key][level_one_key][level_one_key]] is:

[0, 'Response', 0, 'SavingNotification', 0, 'Alternatives']

And here is the function itself:

def get_nested_value_IRFAN(path):   
  return functools.reduce(lambda a,b:a[b],path)

The function should return only the values of the Alternatives key, per my understanding of the code but nothing is returned by the function--just blank [] returns? Or I could use nested_value variable in a different way to extract the values of the Alternative key. I have tried a few things but nothing has worked so far.

Thanks in advance!

6
  • 1
    Why do you think it will ever go to the second element I that list? In the path you have 0. reduce is probably the wrong thing to use here Commented Aug 18, 2022 at 17:41
  • get_nested_value_IRFAN() only gets one value from the specified path. You need a loop to get all of them. Commented Aug 18, 2022 at 17:42
  • Note, you haven't really defined any of the variables you are using in the code, which you really should. Why make people guess? It is simple and straightforward to make this totally unambiguous Commented Aug 18, 2022 at 17:44
  • 1
    Use the key [0, 'Response', 0, 'SavingNotification'] to get to that level, then you can loop and get item['Alternatives'] Commented Aug 18, 2022 at 17:46
  • I am trying to implement what that programmer left behind. Commented Aug 18, 2022 at 17:47

2 Answers 2

1

The approach using reduce is fine, but there are a few problems with your code and/or data:

  • first, your nested_value is not structured properly; there are a few closing parens and a comma missing (and possibly and entire outer layer)
  • instead of chaining the actual data to the path, you can use the third parameter of reduce: initializer
  • the first key in your path is 0, but in your nested_value, the outermost structure is a dictionary

Or should there be another list around that? If there is another list, then [] would actually be the correct response for the given path and data. In any case, I would suggest at least using the initializer parameter to make the code a lot clearer:

nested_value = [{'Response': [{'SavingsMessage': '',
    'SavingNotification': [{'AuthorizationNumber': '12345',
      'Alternatives': []},
     {'AuthorizationNumber': '6666', 'Alternatives': [{'NDC': '99999'}]}]}]}]

def get_nested_value_IRFAN(path, data): 
    return functools.reduce(lambda a, b: a[b], path, data)

# using 1 instead of 0 as last list index for clearer output
path = [0, 'Response', 0, 'SavingNotification', 1, 'Alternatives']

val = get_nested_value_IRFAN(path, nested_value)
# [{'NDC': '99999'}], or [] for original path
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you. You had an extra ] at the end of the nested_value variable. Anyway, after removing that I ran the code just like your Answer above with hard-coded values but get Keyerror 0.
Oh, the extra ] was because was missing the initial [. Anyway, I do now see the NDC values returned; let me confirm something but look like almost there! Thanks!
@IrfanClemson Note that I change a 0 in the path to 1 to get a more "expressive" result and not just [], but for the original path, [] would actually be correct.
Thank you. If I were to make to 0 then still nothing returns. But if 1 then all values are NDC 999 in a loop; I think the [] should also return for downstream check when the Alternatives key doesn't have any value.
Actually, the same NDC values are returned even though other values exist in the nested_value variable. Hmm.
|
0

Because comments are limited in space and formatting, I'm posting an answer.

What you've given us:

nested_value = {
 'Response': 
[
 {
  'SavingsMessage': '', 
  'SavingNotification': 
  [
   {'AuthorizationNumber': '12345' 'Alternatives': []},
   {'AuthorizationNumber': '6666', 'Alternatives': [{'NDC': '99999'} ]
  ]
}

path = [0, 'Response', 0, 'SavingNotification', 0, 'Alternatives']

def get_nested_value_IRFAN(path):
    return functools.reduce(lambda a,b:a[b],path)

get_nested_value_IRFAN([nest_value, path])

functools.reduce() takes a function and a dataset to iterate over. The passed in function stores the result of the previous iteration in a and gets the new value to use in b. On the first iteration it takes in the first 2 elements of the list (path in our case).

So the iterations, while applying the function, look like:

a = the nested_value data structure wrapped in [], b = 0
a = the nested_value data structed, b = "Response"
a = nested_value["Response"], b = 0
a = nested_value["Response"][0], b = "SavingNotification"
a = nested_value["Response"][0]["SavingNotification"], b = 0
# below is the last iteration
a = nested_value["Response"][0]["SavingNotification"][0], b = "Alternatives"
# which returns nested_value["Response"][0]["SavingNotification"][0]["Alternatives"]
# which is also []

You can create a loop to get the other values with minimal effort like so:

dkey = schema[key][level_one_key][level_one_key]
level_two = get_nested_value_IRFAN([nested_value,*dkey[:-2]])
for e in level_two:
    # Okay... so this one should work... but if it doesn't, then you can do...
    print(e[dkey[-1]])
    print(e["Alternatives"]
    # do what you want with e

9 Comments

High. Thank you. So are you going to add the loop? It looks like you started to but that is not there yet?
Oops I see now. Sorry! Thanks.
You're good... I think I threw an error. I just updated it.
Hi, I think we are closer but I get the values of key like AuthorizationNumber while I only need for Alternatives key?
get_nested_value_IRFAN(path) is defined in my answer the same as it is in your post. See the beginning of my answer that explains how that function works.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.