Members Only
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
Problem
A legacy identity system exports employee IDs as strings of digit characters. Downstream reports keep only the odd digits from each ID, in the order they appear.
Every digit wants in. Only the odd ones make the cut.
Example 1
Input:
s = "82931"
Output:
"931"
Example 2
Input:
s = "2468"
Output:
""
Worked solution and explanation
What this really is
Under the employee-ID costume this is a value predicate over a sequence: keep the characters whose numeric value is odd, drop the rest, hand back a string in the same order. Nobody fails the loop itself. Candidates trip on the definition of 'odd'. The tempting shortcuts all read like the answer and all lie: slicing every other character selects by POSITION not value, a set silently drops repeated odds, and sorting throws away the original order. Pick any of them and you don't get a close answer, you get a different string, and on an ID that must round-trip exactly, different is broken.
The shortcuts that look right and aren't
- Positional slice
- s[::2] grabs every other character by index. On '2468' it returns '26', but there are no odd digits, so the answer must be ''. Selecting by position answers a different question than selecting by value.
- Value predicate
- Convert each character to an int and keep it only when the value is odd. On '2468' every digit is even, so nothing survives and you correctly return ''.
How to get there
Step 1: Walk the characters
Scan the input one character at a time. Each character is a digit, so its identity is its value.
Step 2: Test the value, not the index
Convert the character to an int and test parity with modulo 2. This is the line that separates 'odd value' from 'odd position': you are asking about the digit itself, not where it sits.
Step 3: Rebuild in order
Collect survivors in a list and join once at the end. Order and repeats are free because you never reorder, you just skip the evens.
The solution
def filter_odd_digits(s: str) -> str:
result = []
for ch in s:
if int(ch) % 2 != 0:
result.append(ch)
return ''.join(result)Common follow-up questions
- What if the input contained non-digit characters? (Tests adding an `isdigit()` guard before the int conversion.)
- How would you return the even digits instead? (Tests flipping the parity condition.)
- What if you needed both odd and even digits as separate results? (Tests building two result lists in a single pass.)