Python - Itterate down dictionairy - move down tree conditionally

323 views Asked by At

I have a some python code below that walk down a tree but I want it to work down a tree checking taking some paths conditioally based on values. I want to get the LandedPrice for branches of tree based on condition and fulfillmentChannel

parsed_results['LowestLanded'] = sku_multi_sku['Summary']['LowestPrices']['LowestPrice']['LandedPrice']['Amount']['value']

That walks down this tree but values because there are two LowestPrice records/dicts returned one for each condition and fulfillmentChannel pair. I want to filter on condition=new and fulfillmentChannel=Amazon so I only get back one record. When I parse XML data I can do it with code similar to LowestPrices/LowestPrice[@condition='new'][@fulfillmentChannel='Merchant']/LandedPrice/Amount" but couldn't get similar code to work here. How do I do this with dictionaries?

 "LowestPrices":{
     "value":"\n                ",
     "LowestPrice":[
        {
           "value":"\n                    ",
           "condition":{
              "value":"new"               #condtion new
           },
           "fulfillmentChannel":{
              "value":"Amazon"            ## fulfilllmentChannel #1
           },
           "LandedPrice":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"19.57"
              }
           },
           "ListingPrice":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"19.57"
              }
           },
           "Shipping":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"0.00"
              }
           }
        },
        {
           "value":"\n                    ",
           "condition":{
              "value":"new"
           },
           "fulfillmentChannel":{
              "value":"Merchant"
           },
           "LandedPrice":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"19.25"
              }
           },
           "ListingPrice":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"19.25"
              }
           },
           "Shipping":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"0.00"
              }
           }
        }
     ]
  },
3

There are 3 answers

0
Oleksii Tambovtsev On BEST ANSWER

You can use list comprehensions with conditional logic for your purposes like this:

my_dict = {
    "LowestPrices": {
        "value": "\n                ",
        "LowestPrice": [{
            "value": "\n                    ",
            "condition": {
                "value": "new"
            },
            "fulfillmentChannel": {
                "value": "Amazon"
            },
            "LandedPrice": {
                "value": "\n                        ",
                "CurrencyCode": {
                    "value": "USD"
                },
                "Amount": {
                    "value": "19.57"
                }
            },
            "ListingPrice": {
                "value": "\n                        ",
                "CurrencyCode": {
                    "value": "USD"
                },
                "Amount": {
                    "value": "19.57"
                }
            },
            "Shipping": {
                "value": "\n                        ",
                "CurrencyCode": {
                    "value": "USD"
                },
                "Amount": {
                    "value": "0.00"
                }
            }
        },
            {
                "value": "\n                    ",
                "condition": {
                    "value": "new"
                },
                "fulfillmentChannel": {
                    "value": "Merchant"
                },
                "LandedPrice": {
                    "value": "\n                        ",
                    "CurrencyCode": {
                        "value": "USD"
                    },
                    "Amount": {
                        "value": "19.25"
                    }
                },
                "ListingPrice": {
                    "value": "\n                        ",
                    "CurrencyCode": {
                        "value": "USD"
                    },
                    "Amount": {
                        "value": "19.25"
                    }
                },
                "Shipping": {
                    "value": "\n                        ",
                    "CurrencyCode": {
                        "value": "USD"
                    },
                    "Amount": {
                        "value": "0.00"
                    }
                }
            }
        ]
    },
}

lowest_prices = [x for x in my_dict["LowestPrices"]["LowestPrice"] if
                 x["condition"]["value"] == "new"
                 and x["fulfillmentChannel"]["value"] == "Amazon"]

lowest_prices is a list of all dicts that satisfy the required conditions. If you sure that you have only one dictionary in your case that satisfy conditions or you just want to get the amount of the first one, you just do this:

if len(lowest_prices) > 0:
    amount = lowest_prices[0]["LandedPrice"]["Amount"]["value"]
    print(amount)
0
oosstt On

Model approach for this problem

from unittest import TestCase
from pydantic import BaseModel
from typing import List
  
class MdlValue(BaseModel):
    value:str
    
class MdlFulfillment(BaseModel):
    value:str
  
class MdlPrice(BaseModel):
    value:str
    CurrencyCode:MdlValue
    Amount:MdlValue
          
class MdlPrices(BaseModel):
    condition:MdlValue
    fulfillmentChannel:MdlFulfillment
    LandedPrice:MdlPrice
    ListingPrice:MdlPrice
    Shipping:MdlPrice
 
class MdlPricesList(BaseModel):
        value:str
        LowestPrice:List[MdlPrices]
           
class MdlLowestPrices(BaseModel):
    LowestPrices:MdlPricesList
    
    
data =  { 
    "LowestPrices":{
     "value":"\n                ",
     "LowestPrice":[
        {
           "value":"\n                    ",
           "condition":{
              "value":"new"               #condtion new
           },
           "fulfillmentChannel":{
              "value":"Amazon"            ## fulfilllmentChannel #1
           },
           "LandedPrice":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"19.57"
              }
           },
           "ListingPrice":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"19.57"
              }
           },
           "Shipping":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"0.00"
              }
           }
        },
        {
           "value":"\n                    ",
           "condition":{
              "value":"new"
           },
           "fulfillmentChannel":{
              "value":"Merchant"
           },
           "LandedPrice":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"19.25"
              }
           },
           "ListingPrice":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"19.25"
              }
           },
           "Shipping":{
              "value":"\n                        ",
              "CurrencyCode":{
                 "value":"USD"
              },
              "Amount":{
                 "value":"0.00"
              }
           }
        }
     ]
  }
}

class TestStackOverflowQuestens(TestCase):
    
    def test_run1(self):
        x = MdlLowestPrices.parse_obj(data)
        for i in x.LowestPrices.LowestPrice:
               if (i.condition.value == "new" and i.fulfillmentChannel.value == "Amazon"):
                   print(i.ListingPrice.Amount.value) 
0
Anindya Dey On

Here are a couple of ways:

  1. Using filter()

lowest_price = sku_multi_sku['Summary']['LowestPrices']['LowestPrice']

lowest_price_list = list(filter(lambda sku: sku['condition']['value'] == 'new' and sku['fulfillmentChannel']['value'] == 'Amazon'))

# if you are sure that there would be only one item with lowest_price, then
# CAUTION: One should, however, check for the None type
print(lowest_price_list[0]['ListingPrice']['Amount']['value']) # Output: 19.57

  1. Using List Comprehension

lowest_price = sku_multi_sku['Summary']['LowestPrices']['LowestPrice']

lowest_price_list = [i for i in lowest_price if i['condition']['value'] == 'new' and i['fulfillmentChannel']['value'] == 'Amazon']

print(lowest_price_list[0]['ListingPrice']['Amount']['value'])
# Output: 19.57 --> With the same cautionary note as above


NOTE: filter() translates to list comprehension