The Ones That Come Back
An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- easy
- Seniority
- L3
- Asked in
- JPMorgan Chase
Problem
A data-quality check on an event export turned up a column of integer ids that should be unique but isn't. Return the id values that appear more than once, from smallest to largest.
In a column that promised uniqueness, some values kept their seat. Name them.
Example 1
Input:
ids = [1,2,3,2,4,3,5]
Output:
[2,3]
Example 2
Input:
ids = [5,3,5,3,3,1,1]
Output:
[1,3,5]
Worked solution and explanation
What this really is
Strip the event-export framing and this is a frequency filter, not a dedup. The skill being probed: count how many times each id occurs, then keep only the ids whose count reaches two, each reported once, smallest first. The trap is sorted(set(ids)). It reads like "find the duplicates" but returns every distinct id, so a clean column of three unique ids comes back as three violations. The quieter trap is appending an id every time you see it again, which lists an id that appears three times twice.
Two answers that look right
Both wrong turns treat the question as "which ids are in the column" instead of "which ids occur more than once". The set throws away the counts you need. The append-on-repeat loop does notice repeats, but it reports every repeat instead of every repeated id.
- Dedup, or append on every repeat
sorted(set(ids))returns every distinct id, so[10, 20, 30]reports all three. Appending on each re-sight turns[5, 3, 5, 3, 3, 1, 1]into[5, 3, 3, 1]: 3 is listed twice and the order is first-repeat order.- Count, keep repeats, sort
Counter(ids)tallies every id. Keeping the keys withcount > 1lists each offending id exactly once, andsorted()delivers the smallest-to-largest order the report promises.
The solution
Step 1: Tally occurrences in one pass
Counter(ids) walks the list once and maps each id to its count. Without the count you cannot tell a duplicate from a singleton, and the count is exactly what a set loses.
Step 2: Keep only the repeats
Loop over counts.items() and append the ids whose count is above one. Because you are reading keys, each qualifying id is considered once, so an id seen three times still lands once.
Step 3: Sort ascending on the way out
Counter keeps first-seen order, so on [5, 3, 5, 3, 3, 1, 1] the repeats come out as 5, 3, 1. Wrapping them in sorted() produces the smallest-to-largest order the statement promises.
from collections import Counter
def find_duplicates_only(ids: list[int]) -> list[int]:
counts = Counter(ids)
repeated = []
for value, count in counts.items():
if count > 1:
repeated.append(value)
return sorted(repeated)Common follow-up questions
- What if the output had to be in first-seen order instead of ascending? (Tests whether they drop `sorted()` and rely on `Counter`, which already preserves insertion order in modern Python.)
- How would you return the values that appear exactly k times? (Tests generalizing the `count > 1` filter to `count == k` over the same frequency map.)
- If the input were already sorted, could you avoid the counter entirely? (Tests recognizing that adjacent equality exposes duplicates with O(1) extra space.)