
题目考点
这道题主要考这几个点:
- 字典的使用
- 按“第一次出现的顺序”保存数据
- 字符串拆分与重新拼接
- 累加统计
- 输入处理
这题表面上像是在“打印商品和总价”,但真正的核心有两个:
第一,同名商品要合并统计价格总和。
第二,输出顺序必须保持这个商品第一次出现的顺序。
审题
输入是什么
第一行是一个整数 N,表示接下来有多少条购买记录。
后面 N 行,每一行都是:
item_name price
但这里要特别注意:
item_name 不是一定只有一个单词。
比如样例里有:
BANANA FRIES 12
POTATO CHIPS 30
APPLE JUICE 10
这说明:
- 最后一个部分才是价格
- 前面的所有部分拼起来,才是商品名
也就是说,一行不能简单理解成:
name, price = input().split()
因为像 "BANANA FRIES 12" 会被拆成:
['BANANA', 'FRIES', '12']
这时左边只有两个变量,就接不住三个部分。
输出是什么
输出每一种商品:
- 按它第一次出现的顺序
- 打印
item_name net_price
其中:
item_name是商品名net_price是这个商品所有出现次数对应价格的总和
题目要求我们做什么
本质上就是:
把多条购买记录,按商品名分组,然后把同名商品的价格加起来,最后按第一次出现顺序输出。
容易忽略的点
这题最容易忽略的地方有两个:
1. 商品名可能有空格
不能直接写:
name, price = input().split()
因为商品名可能是 "APPLE JUICE"、"POTATO CHIPS" 这种多单词形式。
2. 要保持第一次出现顺序
如果只是单纯统计总价,不考虑顺序,事情很简单。
但题目要求“按照第一次出现顺序输出”,所以你存数据时就要考虑顺序问题。
思路提示
先不要急着写代码,先把过程想清楚。
你可以把每一行输入想成两部分:
第一部分是商品名,第二部分是价格。
但因为价格永远在最后,所以我们可以:
- 先把整行用
split()拆成列表 - 取最后一个元素作为价格
- 把前面的元素重新用空格拼起来,得到商品名
然后,我们需要一个“能记住出现顺序”的字典:
- 如果商品第一次出现,就把它放进去
- 如果商品之前已经出现过,就把价格继续加上去
最后,再按照字典中的顺序逐个输出即可。
完整设计思路
现在把它展开成清晰的 4 步。
第一步:读入记录条数
先读入 N,表示后面有几行商品记录。
第二步:逐行处理每条记录
对于每一行,例如:
APPLE JUICE 10
先做:
parts = input().split()
得到:
['APPLE', 'JUICE', '10']
然后:
parts[-1]是价格parts[:-1]是商品名的所有单词
于是:
price = int(parts[-1])
item_name = " ".join(parts[:-1])
这样就能得到:
item_name = "APPLE JUICE"
price = 10
这一步是整题最关键的输入处理。
第三步:用字典累计总价
准备一个字典来存:
{
商品名: 总价
}
每读到一个商品时:
- 如果它第一次出现,就直接存进去
- 如果已经出现过,就把价格加上去
例如:
APPLE JUICE 10
APPLE JUICE 10
最后会变成:
"APPLE JUICE": 20
第四步:按顺序输出
最后遍历字典,把每个商品名和总价打印出来。
因为我们是按输入顺序逐步加入字典的,所以输出时自然就是“第一次出现的顺序”。
代码实现
这里我先给你一个很适合这道题的写法,使用 OrderedDict,也更贴近这道题原本想考的内容。
from collections import OrderedDict
n = int(input())
items = OrderedDict()
for _ in range(n):
parts = input().split()
price = int(parts[-1])
item_name = " ".join(parts[:-1])
if item_name in items:
items[item_name] += price
else:
items[item_name] = price
for name, total_price in items.items():
print(name, total_price)
运行演示
我们用题目样例来手动模拟一下。
输入:
9
BANANA FRIES 12
POTATO CHIPS 30
APPLE JUICE 10
CANDY 5
APPLE JUICE 10
CANDY 5
CANDY 5
CANDY 5
POTATO CHIPS 30
第 1 行
BANANA FRIES 12
拆分后:
parts = ['BANANA', 'FRIES', '12']
price = 12
item_name = 'BANANA FRIES'
字典变成:
{
'BANANA FRIES': 12
}
第 2 行
POTATO CHIPS 30
字典变成:
{
'BANANA FRIES': 12,
'POTATO CHIPS': 30
}
第 3 行
APPLE JUICE 10
字典变成:
{
'BANANA FRIES': 12,
'POTATO CHIPS': 30,
'APPLE JUICE': 10
}
第 4 行
CANDY 5
字典变成:
{
'BANANA FRIES': 12,
'POTATO CHIPS': 30,
'APPLE JUICE': 10,
'CANDY': 5
}
第 5 行
APPLE JUICE 10
APPLE JUICE 已经出现过,所以累加:
'APPLE JUICE': 10 + 10 = 20
字典变成:
{
'BANANA FRIES': 12,
'POTATO CHIPS': 30,
'APPLE JUICE': 20,
'CANDY': 5
}
后面几行继续累加
最后得到:
{
'BANANA FRIES': 12,
'POTATO CHIPS': 60,
'APPLE JUICE': 20,
'CANDY': 20
}
按顺序输出就是:
BANANA FRIES 12
POTATO CHIPS 60
APPLE JUICE 20
CANDY 20
方法总结
这类题以后你可以这样识别、这样下手。
一看到“按第一次出现顺序输出”
你就要立刻想到:
- 不能只统计
- 还要保留顺序
- 适合用“有顺序的字典”
一看到“同名项目要合并”
你就要想到:
- 用字典做“分组累计”
- 键是名字
- 值是总和
也就是这个模式:
if key in dic:
dic[key] += value
else:
dic[key] = value
一看到“商品名里可能有空格”
你就要想到:
- 不能直接两个变量接收
- 最后一个是数字
- 前面的全部拼回去才是名字
这个模式非常重要:
parts = input().split()
price = int(parts[-1])
name = " ".join(parts[:-1])
这是这道题最核心的输入处理模板。
补充说明:为什么这里常用 OrderedDict
OrderedDict 是 collections 模块里的“有序字典”。
普通字典的重点是“键值对应”。
而 OrderedDict 除了保存键值,还专门强调“插入顺序”。
这道题题意正好是:
- 遇到新商品时记住它第一次出现的位置
- 后面再出现时只更新价格,不改变顺序
所以 OrderedDict 很适合。
在较新的 Python 版本里,普通 dict 也会保留插入顺序,所以很多时候也能写成:
n = int(input())
items = {}
for _ in range(n):
parts = input().split()
price = int(parts[-1])
item_name = " ".join(parts[:-1])
if item_name in items:
items[item_name] += price
else:
items[item_name] = price
for name, total_price in items.items():
print(name, total_price)
不过如果题目本身就在考 OrderedDict,那还是写 OrderedDict 更稳,也更符合出题意图。
本节小结
这道题本质不是难在“统计”,而是难在两件事:
第一,商品名可能有空格,所以要把最后一个元素当价格,前面重新拼接成名字。
第二,既要合并同名商品,又要保留第一次出现顺序,所以适合用 OrderedDict。
以后遇到类似题目,你可以优先套这个思路:
- 先拆输入
- 找出“键”和“值”
- 用字典累计
- 按保存顺序输出
练习
你可以先自己做这道同类型小练习。
题目
第一行输入一个整数 n。
接下来 n 行,每行输入一个“书名”和“销量”,其中书名可能包含空格。
请你按书名第一次出现的顺序,输出每本书的总销量。
例如输入:
6
Harry Potter 3
Data Science 2
Harry Potter 4
Python Basics 5
Data Science 1
Harry Potter 2
期望输出:
Harry Potter 9
Data Science 3
Python Basics 5
提示
你可以直接套用这道题的方法:
split()- 最后一个元素当数字
- 前面用
" ".join(...)拼成名字 - 用字典累计总和



