from itertools import count mapping = {} for letters, number in zip("bfpv cgjkqsxz dt l mn r".split(), count(1)): mapping.update({letter:number for letter in letters}) def soundex(word): word = word.lower() first, rest = word[0], word[1:] digits = [] digit = mapping.get(first) for letter in rest: next_digit = mapping.get(letter) if next_digit is not None and next_digit != digit: digits.append(next_digit) if len(digits) == 3: break digit = next_digit else: digits.extend(0 for x in xrange(3 - len(digits))) return first + "".join(map(str, digits)) assert map(soundex, "euler gauss hilbert knuth lloyd lukasiewicz".split()) \ == map(soundex, "ellery ghosh heilbronn kant ladd lissajous".split()) \ == "e460 g200 h416 k530 l300 l222".split()