Python - Iterar hacia abajo el diccionario - bajar el árbol condiciona

Python - Iterar hacia abajo el diccionario - bajar el árbol condicionalmente

Tengo un código de python a continuación que baja por un árbol, pero quiero que funcione por un árbol comprobando que toma algunas rutas condicionalmente en función de los valores. Quiero obtener el LandedPrice para las ramas del árbol según la condición y fulfillmentChannel

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

Eso recorre este árbol pero tiene valores porque hay dos registros/dicts LowestPrice devueltos uno para cada par condition y fulfillmentChannel. Quiero filtrar por condition=new y fulfillmentChannel=Amazon para obtener solo un registro. Cuando analizo datos XML, puedo hacerlo con un código similar a LowestPrices/LowestPrice[@condition='new'][@fulfillmentChannel='Merchant']/LandedPrice/Amount" pero no pude obtener un código similar para trabajar aquí. ¿Cómo hago esto con los diccionarios?

 "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"
              }
           }
        }
     ]
  },
Mostrar la mejor respuesta

¿Hay una respuesta aquí que solo necesito iterar/recorrer los datos en el nivel en el que estoy en la lista?

Puede usar comprensiones de lista con lógica condicional para su propósitos como este:

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 es una lista de todos los dictados que cumplen las condiciones requeridas. Si está seguro de que solo tiene un diccionario en su caso que cumple con las condiciones o simplemente desea obtener la cantidad del primero, simplemente haga esto:

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

Enfoque modelo para este problema

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) 

Aquí hay un par de formas:

  1. Utilizando 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. Uso de Comprensión de listas

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


NOTA: filter() se traduce como list comprehension