Chique_Code
Chique_Code

Reputation: 1530

access nested dictionary in Python for comparison in for loop

I am trying to access a nested dictionary value to compare with another dictionary's key value. I have two list of dictionaries. Look like the following:

params = [{'nUID': '39', 'Query': [{'MaxRecords': '40', 'OrderName': 'Forecast Placeholder - 1005', 'CustomerID': '15283'}]}]

response = [{
    'OrderID': 1028,
    'Name': 'Forecast Placeholder - 1005',
    'CustomerID': 1127}]

I need to compare OrderName value from params and Name from response. Here is what I have tried:

adpoint_key = "AdPoint_Id__c"
for index, my_dict in enumerate(test_data):
    if my_dict['DBU_Key__c'] != "AUT" and my_dict["AdPoint_Sync_Conditions__c"] != '"' and adpoint_key in my_dict.keys():
        my_dict["OpportunityID"] = my_dict["AdPoint_Id__c"]
        my_dict["CustomerID"] = my_dict["AdPoint_Customer_Id__c"]

        params = []
        params_dict = {}
        params_dict["nUID"] = "39"
        params_dict["Query"] = []
        new_dict = {} 
        new_dict["MaxRecords"] = "40"
        new_dict["OrderName"] = "Forecast Placeholder - " + my_dict["OpportunityID"]
        new_dict["CustomerID"] = my_dict["CustomerID"]
        params_dict["Query"].append(new_dict)
        params.append(params_dict)
#         print(params)

        response = client.service.GetOrders(**params[0]))

        results = []
        for a, b in zip(params, response):
            if b[0]['Name'] == a['Query'][0]['OrderName']:
                results.append(response_dict)
                print(results)

Error: TypeError: string indices must be integers

Upvotes: 1

Views: 130

Answers (5)

jsmart
jsmart

Reputation: 3001

Here is one approach. First, create params and response as per the original post. Note that params contains nested dicts, and response contains flat dicts.

# original data
params = [{'nUID': '39', 
           'Query': [{'MaxRecords': '40', 
                      'OrderName': 'Forecast Placeholder - 1005', 
                      'CustomerID': '15283'}]}]
response = [{
    'OrderID': 1028,
    'Name': 'Forecast Placeholder - 1005',
    'CustomerID': 1127}]

Now use zip to iterate over the lists (i.e., params, response).

results = list()

for p, r in zip(params, response):
    # use .get() for dictionary look-ups, to to emphasize dict vs list access
    if p.get('Query')[0].get('OrderName') == r.get('Name'):
        results.append(r)
        
print(results)
[{'OrderID': 1028, 'Name': 'Forecast Placeholder - 1005', 'CustomerID': 1127}]

Upvotes: 1

18grady
18grady

Reputation: 51

I suspect that the problem is that the actual structure of params does not match how you are accessing it.

It appears that params is a list of dictionaries. Then the first dictionary object contains a key named Query whose value is also a list of dictionaries. The first dictionary object in that list contains a key named Order Name with a corresponding value representing the name.

So, given the example data in params that you show, to retrieve the Order Name value Forecast Placeholder - 1005 you would need to write:

params[0]["Query"][0]["Order Name"]

First retrieve the fist dictionary in the outer list.
Then retrieve the value for the key named Query
Then retrieve the first dictionary in the list represented by that value
Then retrieve the value for the key named Order Name

If this is not what you intended, then you might need to adjust the structure of params.

To get the query that you are currently trying to work it needs to looks like this:

params["Query"]["OrderName"]

and params needs to look like this:

params = {'nUID': '39', 'Query': {'MaxRecords': '40', 'OrderName': 'Forecast Placeholder - 1005', 'CustomerID': '15283'}}

The error you are getting is because you are trying to index into a list with a string instead of and integer when accessing the outer list, then with the brackets how you have them you are trying to index into a string with another string.

If you need more detail let me know in the comments.

EDIT:

It seems like this should do what you want:

results = []
for index, response_dict in enumerate(response):
    if response_dict["Name"] == params[0]["Query"][0]["OrderName"]:
        results.append(response_dict)
            print(results)

EDIT:

Since you are getting a null reference error, try using the "gravestones" technique of debugging...

results = []
for index, response_dict in enumerate(response):
    print response_dict
    print response_dict["Name"]
    print params
    print params[0]
    print params[0]["Query"]
    print params[0]["Query"][0]
    print params[0]["Query"][0]["OrderName"]
    if response_dict["Name"] == params[0]["Query"][0]["OrderName"]:
        results.append(response_dict)
            print(results)

And see which of the print statements it dies on. Also a more complete stack trace would be extremely helpful

Upvotes: 0

Shivam Jha
Shivam Jha

Reputation: 4492

You need to change first two lines of your for loop:

for a, b in zip(params, response):
    if b[0]['Name'] == a['Query'][0]['OrderName']:

Then, it'll work

Upvotes: 0

sarartur
sarartur

Reputation: 1228

To access the value corresponding to key 'OrderName' in the params object you must do:

ordername_value = params[0]['Query'][0]['OrderName']

to access the value corresponding to key 'Name' in the response object you must do:

name_value = response[0]['Name']

You can then do ordername_value == name_value, which will return True if the two values are equivalent and False if they are not.

Upvotes: 0

Paul
Paul

Reputation: 146

There are two mistakes in the code:

  1. params is a list as well so it should be indexed or enumberated as well.

  2. the result from param["query"] is a list as well. You have to specify which of the dictionaries in the list you want to access (although in this case only one is present)

The following code works but I don't know if that is your intended behaviour:

for index, (response_dict, params_dict) in enumerate(zip(response, params)):
    if response_dict["Name"] == params_dict["Query"][0]["OrderName"]:
        results.append(response_dict)
        print(results)

Upvotes: 0

Related Questions