Group Events by an Ordered Attribute List
MixpanelSoftware Engineer · Technical ScreenLast updated
This problem tests recursive data structuring and hierarchical aggregation by mapping flat event logs to a nested tree of counts based on an ordered list of attributes.
Problem Statement
You are given a list of event dictionaries and a list of attribute names representing the hierarchy for aggregation. Your task is to group these events by the provided attributes in the order specified, returning a nested dictionary where each leaf node contains the count of events matching that path.
Function Signature
def group_events(events: list[dict], attributes: list[str]) -> dict:
Requirements
- Iterate through the
eventslist. For each event, traverse the hierarchy defined by the orderedattributeslist. - Create nested levels in your output dictionary corresponding to the values of these attributes.
- The final leaf node at the deepest level should contain an integer representing the count of events sharing that specific combination of attribute values.
- If an attribute key is missing in an event, treat its value as the string
'N/A'.
Example
Input:
events = [
{"type": "click", "browser": "chrome"},
{"type": "click", "browser": "firefox"},
{"type": "click", "browser": "chrome"}
]
attributes = ["type", "browser"]
Output:
{
"click": {
"chrome": 2,
"firefox": 1
}
}
Constraints
eventslist size: 0 to 10,000.attributeslist size: 1 to 5.eventsmay contain arbitrary extra keys; ignore any not in theattributeslist.- If
eventsis empty, return an empty dictionary{}.
Hints
Hint 1
Use a recursive helper function or an iterative approach to traverse the nested dictionary depth by depth for each event.
Hint 2
For each event, verify if the current level of the dictionary exists; if not, initialize it before moving to the next attribute.
Hint 3
Ensure you handle the 'N/A' default value using the `.get(key, 'N/A')` method to maintain consistent dictionary keys.
Follow-up questions
- How would you modify this solution to return the percentage of the total event count for each leaf node instead of raw counts?
- If the number of attributes were significantly large (e.g., 50+), how would you optimize the memory footprint of the nested dictionary?
- How would you change your implementation if the `attributes` list was not provided upfront but discovered dynamically from the event stream?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.