prize18-5 Exercise 2: A Matching Key for User Names ==================================================== Prediction: the first three names (composed, decomposed, upper case) and the fullwidth-letter one should share one key; "Zoe" (no accent) and "zoes" (a different word) stay separate. So six raw names should reduce to three keys. ex2.py: import unicodedata as ud def key(name): return ud.normalize("NFKC", name).casefold() names = ["Zo\u00eb", "Zoe\u0308", "ZO\u00cb", "\uff3a\uff4f\u00eb", "Zoe", "zo\u00ebs"] seen = {} for n in names: seen.setdefault(key(n), []).append(n) for k, group in seen.items(): print(f"{k!r:8} <- {group}") print(len(names), "names,", len(seen), "distinct") print(len({n for n in names}), "distinct if compared raw") Real output (Python 3.14): 'zoë' <- ['Zoë', 'Zoë', 'ZOË', 'Zoë'] 'zoe' <- ['Zoe'] 'zoës' <- ['zoës'] 6 names, 3 distinct 6 distinct if compared raw Note that "Zoë" and "Zoe" stay different: normalization never removes an accent. Whether they should count as the same name is a policy decision for your application, not a Unicode one. Also note that a key like this is for comparison only; display and store the name the user typed.