I just started dictionaries on my class today, now I'm trying to create a cipher based on the keypad of a phone. I have, for example, this dictionary:
2:['a','b','c']
Now, if I wanted to encrypt for example, a, the output would be 21, the two from the dictionary and 1 from the position of a inside it, but I don't really know how to do it. Here's what I've tried so far but isn't working.
def phoneCipher(string):
cipher = ''
keypad = {'2':['a','b','c'],'3':['d','e','f'],'4':['g','h','i'],'5':['j','k','l'],'6' : ['m','n','o'],
'7':['p','q','r','s'],'8':['t','u','v'],'9':['w','x','y','z']}
for i in string:
if i in keypad:
position = keypad.find(i)
cipher = keypad[i] position
return cipher
CodePudding user response:
If you really want to do it that way around, then as @Barmar say's when you check if i in keypad
its checking the keys of the dictionary, i.e. the number values. So that'll never match.
Also seems like you want to get the cipher for each character in the string, thus two nest loops are needed.
I think this works how you wanted.
def phoneCipher(string):
cipher = ''
keypad = {'2':['a','b','c'],'3':['d','e','f'],'4':['g','h','i'],'5':['j','k','l'],'6' : ['m','n','o'],
'7':['p','q','r','s'],'8':['t','u','v'],'9':['w','x','y','z']}
for i in string:
for key in keypad:
if i in keypad[key]:
#position = keypad[key].index(i) # note its index not find, but we don't actually need it
cipher = key
return cipher
Although it terribly inefficient, i'd suggest twisting your dictionary on its head, so it is letters to numbers rather than numbers to letters.
so maybe:
def phoneCipher2(string):
cipher = ''
keypad = {'a':'2','b':'2','c':'2',
'd':'3','e':'3','f':'3',
'g':'4','h':'4','i':'4',
'j':'5','k':'5','l':'5',
'm':'6','n':'6','o':'6',
'p':'7','q':'7','r':'7','s':'7',
't':'8','u':'8','v':'8',
'w':'9','x':'9','y':'9','z':'9',}
for i in string:
cipher = keypad[i]
return cipher
CodePudding user response:
There are two basic options you can do. One is to iterate each list
in the dict
and then iterate the list
and see if the value is in there. The other is to have a forward and a reverse dict
. This takes up more memory but is much faster.
Option 1 Iterate list
in dict
def phoneCipher(string):
cipher = ''
keypad = {'2': ['a', 'b', 'c'], '3': ['d', 'e', 'f'], '4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'], '6': ['m', 'n', 'o'], '7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'], '9': ['w', 'x', 'y', 'z']}
for c in string:
for number, letters in keypad.items():
if c in letters:
cipher = number str(letters.index(c))
return cipher
Option 2 Use reverse lookup dict
keypad = {'2': ['a', 'b', 'c'], '3': ['d', 'e', 'f'], '4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'], '6': ['m', 'n', 'o'], '7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'], '9': ['w', 'x', 'y', 'z']}
# Creating a reverse dict should be done only once and saved for future/repeated use
reverse_lookup = dict()
for number, letters in keypad.items():
for index, letter in enumerate(letters):
reverse_lookup[letter] = number str(index)
def phoneCipher(string):
return ''.join(map(lambda char: reverse_lookup[char], string))
CodePudding user response:
Try this,
def phoneCipher(string):
cipher = ''
keypad = {'2':['a','b','c'],'3':['d','e','f'],'4':['g','h','i'],'5':['j','k','l'],'6' : ['m','n','o'],
'7':['p','q','r','s'],'8':['t','u','v'],'9':['w','x','y','z']}
for i in string:
for key in keypad:
if i in keypad[key]:
cipher = key
continue
return cipher
phoneCipher("ishan")
Output -
47426