避免嵌套循环分隔列表dicts python

2024-09-27 02:18:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些问题,所以我必须在列表中合并一个单独的dicts,并像下面预期的代码那样显示它

所以我有这些数据:

product_data = [
        {
            'productId': 1000,
            'productName': 'Product 1000'
        },
        {
            'productId': 1001,
            'productName': 'Product 1001'
        }
    ]

stock_data = [
        {
            'productId': 1000,
            'locationId': 1,
            'stock': 21
        },
        {
            'productId': 1000,
            'locationId': 2,
            'stock': 8
        },
        {
            'productId': 1001,
            'locationId': 1,
            'stock': 4
        },
        {
            'productId': 1001,
            'locationId': 2,
            'stock': 10
        }
    ]

location_data = [
        {
            'locationId': 1,
            'locationName': 'Location 1'
        },
        {
            'locationId': 2,
            'locationName': 'Location 2'
        }
    ]

我已经建立了一些方法来处理它的关系。像这样:

def location_detail(self, location_id):
    location_detail = dict()
    for data in self.location_data:
        if data.get('locationId') == location_id:
            location_detail = {
                'locationName': data.get('locationName')
            }
    return location_detail

def total_stock(self, product_id):
    total = 0
    for data in self.stock_data:
        if data.get('productId') == product_id:
            total += data.get('stock')
    return total

def stock_detail(self, product_id):
    stock_detail = []
    for data in self.stock_data:
        if data.get('productId') == product_id:
            stock_detail.append(
                {
                    'stock': data.get('stock'),
                    'location': 
self.location_detail(data.get('locationId')).get('locationName')
                }
            )
    return stock_detail

def get(self):
    result = []
    for data in self.product_data:
        product_id = data.get('productId')
        product_data = {
            'productName': data.get('productName'),
            'stock': {
                'total': self.total_stock(product_id),
                'detail': self.stock_detail(product_id)
            }
        }
        result.append(product_data)
    return result

预期结果是:

const result = [
{
  productName: 'Product 1000',
  stock: {
  total: 29,
  detail: [
    {
      locationName: 'Location 1',
      stock: 21
    },
    {
      locationName: 'Location 2',
      stock: 8
    }
  ]
 }
},
{
productName: 'Product 1001',
stock: {
  total: 14,
  detail: [
    {
      locationName: 'Location 1',
      stock: 4
    },
    {
      locationName: 'Location 2',
      stock: 10
       }
      ]
   }
 }
  ];

但循环次数太多,不符合要求。我想要的是,在没有那么多for循环的情况下,用它的关系获取所有数据


Tags: selfidfordatagetstocklocationproduct
2条回答

这将在列表中迭代一次,但stock_data除外

# convert the location_data into a dict for easy lookup
locations = dict()
for location in location_data:
    locations[location["locationId"]] = location["locationName"]

# convert the stock_data into a dict for easy lookup
stocks = dict()
for stock in stock_data:
    if stock["productId"] in stocks:
        stocks[stock["productId"]]["stockamounts"][stock["locationId"]] = stock["stock"]
        stocks[stock["productId"]]["total"] += stock["stock"]
    else:
        stocks[stock["productId"]] = {
            "total": stock["stock"],
            "stockamounts": {stock["locationId"]: stock["stock"]},
        }

# iterate through the products
result = list()
for product in product_data:
    # set the simple variables
    item = {
        "productName": product["productName"],
        "stock": {
            "total": stocks[product["productId"]]["total"],
            "detail": []}
    }
    # populate the detail list
    for key, value in stocks[product["productId"]]["stockamounts"].items():
        item["stock"]["detail"].append({
            "locationName": locations[key],
            "stock": value
            })
    result.append(item)

我能想到的唯一一件事,他们的意思是使用列表理解而不是for循环

您可能会发现一些关于该主题的有用链接:

def aggregate_stock_data(prod_inf, stock_inf, loc_inf):
    loc_inf = {loc['locationId']: loc['locationName'] for loc in loc_inf}
    stock_inf = {
        prod['productId']: list(filter(
            lambda x: x['productId'] == prod['productId'],
            stock_inf
        )) for prod in prod_inf
    }
    aggregated = [
        {
            'productName': prod['productName'],
            'stock': {
                'total': sum(
                    item['stock']
                    for item in stock_inf[prod['productId']]
                ),
                'detail': [
                    {
                        'stock': item['stock'],
                        'locationName': loc_inf[item['locationId']]
                    } for item in stock_inf[prod['productId']]
                ]
            }
        } for prod in prod_inf
    ]
    return aggregated

如果由于某种原因,情况并非如此,则始终可以使用map函数。但我认为这通常会使代码比现在更不可读

def aggregate_stock_data(prod_inf, stock_inf, loc_inf):
    loc_inf = {loc['locationId']: loc['locationName'] for loc in loc_inf}
    stock_inf = {
        prod['productId']: list(filter(
            lambda x: x['productId'] == prod['productId'],
            stock_inf
        )) for prod in prod_inf
    }
    aggregated = list(map(
        lambda prod: {
            'productName': prod['productName'],
            'stock': {
                'total': sum(map(
                    lambda x: x['stock'],
                    stock_inf[prod['productId']])
                ),
                'detail': list(map(
                    lambda x: {
                        'stock': x['stock'],
                        'locationName': loc_inf[x['locationId']]
                    }, stock_inf[prod['productId']]
                ))
            }
        }, prod_inf
    ))
    return aggregated

相关问题 更多 >

    热门问题