Katkat

Group Events by an Ordered Attribute List

MixpanelSoftware Engineer · Technical Screen

Last 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

  1. Iterate through the events list. For each event, traverse the hierarchy defined by the ordered attributes list.
  2. Create nested levels in your output dictionary corresponding to the values of these attributes.
  3. The final leaf node at the deepest level should contain an integer representing the count of events sharing that specific combination of attribute values.
  4. 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

  • events list size: 0 to 10,000.
  • attributes list size: 1 to 5.
  • events may contain arbitrary extra keys; ignore any not in the attributes list.
  • If events is 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?