I wrote a straightforward function that converts letters in words to their 'leet' numerical counterparts.
def Leet(word):
letters = list(word.lower())
for n, letter, in enumerate(letters):
if letter == 'o':
letters[n]= '0'
elif letter == 'i':
letters[n]= '1'
elif letter == 'z':
letters[n]= '2'
elif letter == 'e':
letters[n]= '3'
elif letter == 'a':
letters[n]= '4'
elif letter == 's':
letters[n]= '5'
elif letter == 'g':
letters[n]= '6'
elif letter == 't':
letters[n]= '7'
elif letter == 'b':
letters[n]= '8'
return ''.join(letters)
so when I input 'zit'
, the program will return '217'
.
My question is, how can I change it to give me every possible result ('217'
, '2it'
, 'z1t'
, 'zi7'
, '21t'
, etc.)? I've read about itertools
but I am stumped as to how to apply it to my function.
First observation is that you can shorten the lookup, like this:
REPLACE = { letter: str(index) for index, letter in enumerate('oizeasgtb') }
def Leet2(word):
letters = [ REPLACE.get(l, l) for l in word.lower() ]
return ''.join(letters)
REPLACE
looks like:
{'a': '4', 'b': '8', 'e': '3', 'g': '6', 'i': '1',
'o': '0', 's': '5', 't': '7', 'z': '2'}
And the REPLACE.get(l,l)
gives you back either the replacement letter, or the original letter if there is no replacement.
The second observation is that you don't really want permutations, which are shifts in ordering. The permutations of '217' are:
>>> [ ''.join(p) for p in permutations('217') ]
['217', '271', '127', '172', '721', '712']
What you really need is the product of a list that encodes all the possible choices for a given character position:
[('z', '2'), ('i', '1'), ('t', '7')]
How this works might be clearer if I also show a possibility list with some characters for which there is no valid replacement. For 'red'
for example:
[('r',), ('e', '3'), ('d',)]
Now we need the string-joined product of those options. Putting it all together:
from itertools import product
def Leet2Combos(word):
possibles = []
for l in word.lower():
ll = REPLACE.get(l, l)
possibles.append( (l,) if ll == l else (l, ll) )
return [ ''.join(t) for t in product(*possibles) ]
print Leet2Combos('zit')
print Leet2Combos('red')
Gives:
['zit', 'zi7', 'z1t', 'z17', '2it', '2i7', '21t', '217']
['red', 'r3d']