File: keyboard-row/solution.py

Date: 2026-06-06

Time: 17:11

keyboard-row/solution.py

Purpose

This file solves LeetCode 500 — Keyboard Row: given a list of words, return only those that can be typed using letters from a single row of an American QWERTY keyboard. It's a self-contained module owning both the solution and its test suite.

Key Components

find_words(words: list[str]) -> list[str] — The sole public function. Takes a list of strings and filters it down to words whose letters all belong to one keyboard row.

row_map (line 13) — A dict mapping each lowercase letter to its row index (0 = top row qwertyuiop, 1 = home row asdfghjkl, 2 = bottom row zxcvbnm). Built inline via a dict comprehension over enumerate.

TestFindWords (lines 17–38) — Eight unit tests covering the LeetCode examples plus edge cases: single characters, all-uppercase, mixed case, no matches, and all matches.

Patterns

Set-cardinality check — The core logic is a single list comprehension (line 14):


[w for w in words if len(set(row_map[c] for c in w.lower())) == 1]

For each word, it maps every character to its row index, collects those into a set, and checks whether the set has exactly one element. If so, all letters share a row. This is idiomatic Python — compact and avoids explicit loops or conditionals.

Single-file solution+test — The solution and its unittest.TestCase live in the same file, runnable via python -m unittest or python solution.py. This is the standard pattern across the repo.

Dependencies

Imports: Only unittest from the standard library. No external packages.

Imported by: The testsolution.py files listed in the Imported By section don't actually import *this* file — that list appears to be a repo-wide cross-reference artifact. The real consumer is keyboard-row/testsolution.py, which likely imports find_words from this module.

Flow

1. Build rowmap once per call — enumerate assigns index 0/1/2 to the three row strings, then the nested comprehension unpacks each string's characters into {char: rowindex} pairs.

2. For each word w, lowercase it, look up every character in row_map, collect the row indices into a set.

3. If the set has size 1, every letter hit the same row — keep the word (preserving original casing).

4. Return the filtered list.

Invariants

Error Handling

None. If a word contains a character not in row_map (anything outside a-zA-Z), the generator expression inside set(...) raises an unhandled KeyError. This is acceptable because the LeetCode problem guarantees alphabetic-only input.