S2Q2 · Group and Sum Values by Key¶
⚡ Quick Reference
Type: Full I/O problem
Core idea: parse each line into key + values, accumulate totals in a dict, print in sorted key order.
n = int(input())
totals = {}
for _ in range(n):
line = input()
key, vals = line.split(":")
nums = map(int, vals.split(","))
totals[key] = totals.get(key, 0) + sum(nums)
for key in sorted(totals):
print(key, totals[key])
Key rules:
- Split on ":" to separate key and values
- Split values on ",", convert to int, sum
- Use dict.get(key, 0) to accumulate - handles repeated keys
- Print in sorted() key order
Problem Statement¶
Problem (I/O type)
Read n lines. Each line has a key, a colon, and comma-separated integers. Group by key, sum all values per key, and print totals in sorted key order.
Example:
4
p:2,4
q:1,3,5
p:6
r:0
p 12
q 9
r 0
Understanding the problem¶
Two things to handle:
- Parsing - split each line on
":"then values on"," - Grouping - the same key can appear on multiple lines (
pappears twice)
"p:2,4" → key="p", vals=[2,4] → sum=6
"q:1,3,5" → key="q", vals=[1,3,5] → sum=9
"p:6" → key="p", vals=[6] → sum=6 (add to existing p total)
"r:0" → key="r", vals=[0] → sum=0
totals = {"p": 12, "q": 9, "r": 0}
sorted keys: p, q, r → print each
dict.get(key, 0) for accumulation
totals[key] = totals.get(key, 0) + sum(nums) either adds to an existing key's total or starts from 0 if the key hasn't been seen yet. Clean one-liner that avoids an if key in totals check.
Tracing the example¶
| Line | key |
vals |
sum |
totals after |
|---|---|---|---|---|
p:2,4 |
p |
[2,4] |
6 | {p:6} |
q:1,3,5 |
q |
[1,3,5] |
9 | {p:6, q:9} |
p:6 |
p |
[6] |
6 | {p:12, q:9} |
r:0 |
r |
[0] |
0 | {p:12, q:9, r:0} |
Sorted keys: p, q, r → output p 12, q 9, r 0
Solution approaches¶
from collections import defaultdict
n = int(input())
totals = defaultdict(int)
for _ in range(n):
key, vals = input().split(":")
totals[key] += sum(map(int, vals.split(",")))
for key in sorted(totals):
print(key, totals[key])
defaultdict(int) auto-initialises missing keys to 0, so += always works without a guard. Cleaner than dict.get.
from functools import reduce
n = int(input())
lines = [input().split(":") for _ in range(n)]
# Build totals dict using reduce
def accumulate(acc, kv):
key, vals = kv
acc[key] = acc.get(key, 0) + sum(map(int, vals.split(",")))
return acc
totals = reduce(accumulate, lines, {})
list(map(lambda k: print(k, totals[k]), sorted(totals)))
reduce accumulates all lines into the dict in a single pass. The final map(lambda k: print(...)) outputs sorted results functionally.
Key takeaways¶
dict.get(key, 0) for safe accumulation
totals.get(key, 0) + new_sum handles both new and existing keys in one expression. Equivalent to if key in totals: ... else: totals[key] = 0 but far more compact.
sum(map(int, vals.split(","))) - parse and sum in one line
vals.split(",") gives string tokens. map(int, ...) converts each to int. sum(...) totals them. Three operations chained without any intermediate list.
sorted(dict) iterates keys in order
for key in sorted(totals) iterates over the dictionary's keys in ascending sorted order. No need to sort the items - just sort the keys.