By What They Answer To
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L3
Problem
An event family is every event-type name that starts with the same character, matched exactly as written. events is a list of event-type names in the order they came off the message bus. Return a dict mapping each starting character to its family, with the names listed in arrival order.
Every name reports to its first letter. Sort the roll call as it comes in.
Example 1
Input:
events = ["login","logout","click","checkout","signup"]
Output:
{"l":["login","logout"],"c":["click","checkout"],"s":["signup"]}Example 2
Input:
events = []
Output:
{}Worked solution and explanation
What this really is
This is bucket accumulation wearing a grouping costume. The output is a dict of lists, and that shape is the entire point: a list or a set can tell you which first letters showed up, but only a dict of lists can hold, per letter, every name that starts with it in arrival order. Anyone can write the loop. What separates candidates is the first-occurrence case: the moment a key appears for the first time its bucket does not exist yet, and if you index groups[key] before creating the list, or write groups[key] = event instead of appending, every earlier name that shared that letter vanishes. Get that wrong and each letter keeps only its last name, so every multi-item group quietly collapses to one.
How to get there
Step 1: Derive the key
The first character is the partition key. You read it once per name with event[0]; the inputs are real names, so there is always a character to read.
Step 2: Create-then-append, in one pass
Before appending, make sure the bucket exists. setdefault(key, []) returns the existing list or creates an empty one in a single step, then you append. Because you scan left to right and only ever append, within-group order matches input order for free.
The solution
def group_events(events):
groups = {}
for event in events:
groups.setdefault(event[0], []).append(event)
return groupsOne pass, one bucket per first letter, appended in arrival order.
- Overwrite (wrong)
- groups[key] = event assigns a single name to the key. The second name that shares a letter replaces the first, so 'logout' erases 'login' and the group ends with one element.
- Accumulate (right)
- groups.setdefault(key, []).append(event) keeps a growing list per key, so every name that shares a letter is retained in order.
Common follow-up questions
- What if grouping should be case-insensitive? (Tests normalizing the key with .lower() while preserving the original name.)
- How would you group by an arbitrary key function instead of the first character? (Tests accepting a callable so the grouping key is computed by `key_fn`(item).)
- What if the returned groups should come back sorted by key? (Tests wrapping the result in dict(sorted(groups.items())) without disturbing within-group order.)