The Tag Analyst

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
L4
Asked in
Gemini

Problem

A platform engineer is reconciling the tags on two resources, where either list may repeat a tag but each tag only ever counts once. Split them into the tags on both tags_a and tags_b, the ones only in tags_a, and the ones only in tags_b, each group in alphabetical order.

Two sets of labels, one analysis.

Example

Input:

tags_a = ["python","sql","spark"], tags_b = ["sql","spark","airflow"]

Output:

{"both":["spark","sql"],"only_a":["python"],"only_b":["airflow"]}

Worked solution and explanation

This is set algebra dressed up as tag reconciliation. Anyone can name the three buckets. What separates candidates is collapsing the repeats before partitioning, then putting each bucket back into a fixed order. Write [t for t in tags_a if t not in tags_b] and an input like ['python', 'python', 'sql'] hands back 'python' twice in the only-in-a group. Return the raw sets instead and the order shifts from run to run, so a graded, alphabetical answer stops being reproducible.

Walking it through

Step 1: Collapse each list into a set

The statement says a tag only ever counts once, so set(tags_a) and set(tags_b) are the real inputs. Deduplication happens here, once, before any comparison.

Step 2: Partition with & and -

Shared tags are set_a & set_b. Each exclusive group is a difference taken in its own direction: set_a - set_b and set_b - set_a. Those three sets cover every tag exactly once.

Step 3: Sort every group, not just one

A set has no order you can promise. sorted() turns each group into an alphabetical list, and that is the only order that is stable across runs and matches what the example shows.

Set intersection and difference operations
def compare_tags(tags_a: list, tags_b: list) -> dict:
    set_a = set(tags_a)
    set_b = set(tags_b)
    both = set_a & set_b
    only_a = set_a - set_b
    only_b = set_b - set_a
    result = {
        "both": sorted(both),
        "only_a": sorted(only_a),
        "only_b": sorted(only_b)
    }
    return result
Comprehension over the raw lists
[t for t in tags_a if t not in tags_b] keeps every repeat and keeps input order. It also runs O(n*m), because in on a list is a scan.
Sets, then sort
sorted(set_a - set_b) drops repeats, runs in linear time to build, and comes out alphabetical no matter how the inputs were ordered.

Common follow-up questions