You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字典更新:生成含多厂商列表的零件最优报价字典

问题描述

我有一个包含各类零件及厂商报价的DataFrame,约10000个零件、10个厂商,数据集最多含100000行,数据结构如下:

零件(Part)厂商(Maker)价格(Price)
1Alpha1.00
2Alpha1.30
3Alpha1.25
1Bravo1.10
2Bravo1.02
3Bravo1.15
4Bravo1.19
1Charlie0.99
2Charlie1.10
3Charlie1.12
4Charlie1.19

我希望基于最优价格生成两个字典:

  1. 零件-价格字典:每个零件对应最低报价
  2. 零件-厂商字典:每个零件对应报价最低的厂商,若多个厂商报价相同则存为列表

期望输出:

  • 零件-价格字典:
    {1:0.99, 2:1.1, 3:1.02, 4:1.19}
    
  • 零件-厂商字典:
    {1:'Charlie', 2:'Charlie', 3:'Bravo', 4:['Bravo', 'Charlie']}
    

第一个字典实现无难度,但第二个字典处理多厂商同价时出错。最初代码:

winning_price_dict={}
winning_mfg_dict={}
for index, row in quote_df.iterrows():
   if row['Part'] not in winning_price_dict:
       winning_price_dict[row['Part']] = row['Proposed Quote']
       winning_mfg_dict[row['Part']] = list(row['Maker'])
   if winning_price_dict[row['Part']]>row['Proposed Quote']:
       winning_price_dict[row['Part']] = row['Proposed Quote']
       winning_mfg_dict[row['Part']] = row['Maker']
   if winning_price_dict[row['Part']]==row['Proposed Quote']:
       winning_price_dict[row['Part']] = row['Proposed Quote']
       winning_mfg_dict[row['Part']] = winning_mfg_dict[row['Part']].append(row['Maker']) # 此处报错

运行提示'str'对象无append属性,修改后代码:

for index, row in quote_df.iterrows():
if row['Part'] not in winning_price_dict:
    winning_mfg_dict[row['Part']] = list(row['Mfg'])
if winning_price_dict[row['Part']]>row['Proposed Quote']:
    winning_mfg_dict[row['Part']] = list(row[['Mfg']])
if winning_price_dict[row['Part']]==row['Proposed Quote']:
    winning_mfg_dict[row['Part']] = list(winning_mfg_dict[row['Part']]).append(row['Mfg'])

此时winning_mfg_dict全部为None,求修正方案。

解决方案

错误原因

  1. 最初代码中,遇到更低价格时把winning_mfg_dict的值设为字符串,后续执行append时自然报错——字符串没有append方法。
  2. 修改后的代码里,list.append()是原地修改列表,返回值为None,直接赋值会导致字典值变成None。

修正代码(循环版)

核心思路:始终让winning_mfg_dict的值保持为列表,最后按需将单元素列表转为字符串:

winning_price_dict = {}
winning_mfg_dict = {}

for index, row in quote_df.iterrows():
    part = row['Part']
    price = row['Price']  # 原代码里的'Proposed Quote'对应数据集的'Price'
    maker = row['Maker']
    
    if part not in winning_price_dict:
        # 首次记录零件,初始化价格和厂商列表
        winning_price_dict[part] = price
        winning_mfg_dict[part] = [maker]
    else:
        current_min = winning_price_dict[part]
        if price < current_min:
            # 找到更低价格,更新价格并重置厂商列表
            winning_price_dict[part] = price
            winning_mfg_dict[part] = [maker]
        elif price == current_min:
            # 同价厂商追加到列表,加去重判断避免重复
            if maker not in winning_mfg_dict[part]:
                winning_mfg_dict[part].append(maker)

# 把单元素列表转为字符串,匹配期望输出格式
for part in winning_mfg_dict:
    if len(winning_mfg_dict[part]) == 1:
        winning_mfg_dict[part] = winning_mfg_dict[part][0]

优化方案(大数据量适配)

针对10万行的数据集,iterrows()效率较低,推荐用Pandas分组聚合实现,性能更优:

# 先按零件分组,获取每个零件的最低价格字典
min_prices = quote_df.groupby('Part')['Price'].min().to_dict()

# 筛选出所有报价等于最低价格的行,按零件分组收集厂商
winning_makers = quote_df[quote_df.apply(lambda x: x['Price'] == min_prices[x['Part']], axis=1)]\
    .groupby('Part')['Maker'].agg(list).to_dict()

# 处理单元素列表转字符串
for part in winning_makers:
    if len(winning_makers[part]) == 1:
        winning_makers[part] = winning_makers[part][0]

内容的提问来源于stack exchange,提问作者Stephen Juza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:15:34