How can I replace certain characters in a string? - python

I'm relatively new to python(3.5.2) and I'd love some help with my assignment on lists& strings.
I am required to write a code that replaces: e and E with 3, a and A with 4, i and I with 1, o and O with 0 in any given string. Here is my attempt:
s = input("Enter a string: ")
leet = {'a':'4','e':'3','i':'1','o':'0','A':'4','E':'3','I':'1','O':'0'}
for character in s:
if character == leet.keys():
str.replace(leet.keys(),leet.values())
print(s)
This code does not yield any satisfying results for me, I'm wondering if I can use the str.replace method or is there any easier way of doing this?
Thanks!

you can do that in one line using a generator comprehension converted to a string using str.join (Using dict.get with defaults to the input character if not found in dictionary):
s = "a string Entered"
leet = {'a':'4','e':'3','i':'1','o':'0','A':'4','E':'3','I':'1','O':'0'}
crypted = "".join(leet.get(k,k) for k in s)
print(crypted)
result:
4 str1ng 3nt3r3d

replace() method is good. But you use it wrong. Remember that leet.keys() will return a list of all keys in the dictionary. So I suggest this:
s = input("Enter a string: ")
leet = {'a': '4', 'e': '3', 'i': '1', 'o': '0', 'A': '4', 'E': '3', 'I': '1', 'O': '0'}
for k, v in leet.items(): #iterating through dictionary (not string)
s = s.replace(k, v)
print(s)

Related

Lists and dictionary conversion in python

So in the following program I have comes up with something that isn't working the way I want, and I need help figuring this out.
The first input takes a string
"Joe,123-5432 Linda,983-4123 Frank,867-5309"
It first replaces commas with white space, and converts it into list.
['Joe', '123-5432', 'Linda', '983-4123', 'Frank', '867-5309']
However, I want to convert this list into a dictionary using the first entry as the key, and the second entry as the value. So it would look like this:
{'Joe':'123-5432', 'Linda':'983-4123', 'Frank':'867-5309'}
This is where I find my problem (within the function). When I call it into the function it broke it up by individual characters, rather than seeing the .splits as a whole string, which looks like this...
{'J': 'o', 'e': ' ', '1': '2', '3': ' ', '5': '3', ' ': '9', 'i': 'n', 'd': 'a', '8': '6', '-': '4', 'F': 'r', 'a': 'n', 'k': ' ', '7': '-', '0': '9'}
Which ya know is funny, but not my target here.
Later in the program, when Ecall gets an input, it cross references the list and pulls the phone number from the dictionary. Can you help me build a better comprehension for Pdict in the function that does this and not whatever I did?
def Convert(FormatInput):
Pdict = {FormatInput[i]: FormatInput[i + 1] for i in range(0, len(FormatInput), 2)}
return Pdict
user_input = input()
FormatInput=user_input.replace(",", " ")
Pdict=Convert(FormatInput)
Ecall = (input())
print(Pdict.get(Ecall, 'N/A'))
Use two different split operations instead of doing the replace to try to do it in a single split (which just makes things more difficult because now you've lost the information of which separator was which).
First split the original string (on whitespace) to produce a list of comma-separated entries:
>>> user_input = "Joe,123-5432 Linda,983-4123 Frank,867-5309"
>>> user_input.split()
['Joe,123-5432', 'Linda,983-4123', 'Frank,867-5309']
and then split on the commas within each entry so you have a sequence of pairs that you can pass to dict(). You can do the whole thing in one easy line:
>>> dict(entry.split(",") for entry in user_input.split())
{'Joe': '123-5432', 'Linda': '983-4123', 'Frank': '867-5309'}

python - check if word is in list full of strings and if there is print the words in an another list

so basically it would be like:
MyList=["Monkey","Phone","Metro","Boom","Feet"]
and let's say I have the input be m so Boom and Monkey and Metro would be put in a list like so
output >> ["Monkey","Metro","Feet"]
and if I would've had the input be f then the output would be
output >> ["Feet"]
and my question is how would I put this in a def? This is what I came up with
def Find(word,MyList):
MyList2=[]
count=0
for i in MyList:
count+=1
if i[count] == MyList2: ##(at first i did if i[0:10])
for x in range(1):
MyList2.append(i)
print(MyList2)
and then somewhere there should be
word=input("Word, please.")
and then
Find(word,MyList)
thanks in advance!
Try this :
def find_words(input_char, my_list):
ret_list = []
for i in my_list:
if input_char.lower() in i.lower():
ret_list.append(i)
return ret_list
MyList=["Monkey","Phone","Metro","Boom","Feet"]
input_char=input("Input a character :").strip() # get a character and strip spaces if any.
find_words(input_char, MyList) # call the function with arguments
Output for sample input "M :
Input a character :>? "M"
>>> ['Monkey', 'Metro', 'Boom']
(Almost) One liner:
>>> MyList=["Monkey","Phone","Metro","Boom","Feet"]
>>> target = input("Input string: ")
Input string: Ph
>>> print([i for i in MyList if target.lower() in i.lower()])
['Phone']
Generally in Python you don't want to be playing with indexes, iterators are the way to go.
The in keyword checks for substrings so it will work whether you provide only one character or a full string too (i.e. if you input Ph you'll get a list containing only Phone)
Depending on how efficient you want your search would be. Throwing in one more approach to build a dictionary like this
from collections import defaultdict
d = defaultdict(set)
for i in MyList:
chars = set(i)
for c in chars:
d[c].add(i)
Now, your dictionary looks like this
defaultdict(set,
{'o': {'Boom', 'Metro', 'Monkey', 'Phone'},
'k': {'Monkey'},
'e': {'Feet', 'Metro', 'Monkey', 'Phone'},
'M': {'Metro', 'Monkey'},
'y': {'Monkey'},
'n': {'Monkey', 'Phone'},
'h': {'Phone'},
'P': {'Phone'},
't': {'Feet', 'Metro'},
'r': {'Metro'},
'm': {'Boom'},
'B': {'Boom'},
'F': {'Feet'}})
Now, you can simply search within your dict with O(1) complexity
d[your_input_char]
Here is how you can use a list comprehension:
def Find(letter, MyList):
print([word for word in MyList if letter.lower() in word.lower()])
Find('m', ["Monkey","Phone","Metro","Boom","Feet"])
Output:
['Monkey', 'Metro', 'Boom']

Converting colon separated list into a dict?

I wrote something like this to convert comma separated list to a dict.
def list_to_dict( rlist ) :
rdict = {}
i = len (rlist)
while i:
i = i - 1
try :
rdict[rlist[i].split(":")[0].strip()] = rlist[i].split(":")[1].strip()
except :
print rlist[i] + ' Not a key value pair'
continue
return rdict
Isn't there a way to
for i, row = enumerate rlist
rdict = tuple ( row )
or something?
You can do:
>>> li=['a:1', 'b:2', 'c:3']
>>> dict(e.split(':') for e in li)
{'a': '1', 'c': '3', 'b': '2'}
If the list of strings require stripping, you can do:
>>> li=["a:1\n", "b:2\n", "c:3\n"]
>>> dict(t.split(":") for t in map(str.strip, li))
{'a': '1', 'b': '2', 'c': '3'}
Or, also:
>>> dict(t.split(":") for t in (s.strip() for s in li))
{'a': '1', 'b': '2', 'c': '3'}
If I understand your requirements correctly, then you can use the following one-liner.
def list_to_dict(rlist):
return dict(map(lambda s : s.split(':'), rlist))
Example:
>>> list_to_dict(['alpha:1', 'beta:2', 'gamma:3'])
{'alpha': '1', 'beta': '2', 'gamma': '3'}
You might want to strip() the keys and values after splitting in order to trim white-space.
return dict(map(lambda s : map(str.strip, s.split(':')), rlist))
You mention both colons and commas so perhaps you have a string with key/values pairs separated by commas, and with the key and value in turn separated by colons, so:
def list_to_dict(rlist):
return {k.strip():v.strip() for k,v in (pair.split(':') for pair in rlist.split(','))}
>>> list_to_dict('a:1,b:10,c:20')
{'a': '1', 'c': '20', 'b': '10'}
>>> list_to_dict('a:1, b:10, c:20')
{'a': '1', 'c': '20', 'b': '10'}
>>> list_to_dict('a : 1 , b: 10, c:20')
{'a': '1', 'c': '20', 'b': '10'}
This uses a dictionary comprehension iterating over a generator expression to create a dictionary containing the key/value pairs extracted from the string. strip() is called on the keys and values so that whitespace will be handled.

Adding dictionary keys and values after line split?

If I have for instance the file:
;;;
;;;
;;;
A 1 2 3
B 2 3 4
C 3 4 5
And I want to read it into a dictionary of {str: list of str} :
{'A': ['1', '2', '3'], 'B': ['2', '3', '4'], 'C': ['3', '4', '5']
I have the following code:
d = {}
with open('file_name') as f:
for line in f:
while ';;;' not in line:
(key, val) = line.split(' ')
#missingcodehere
return d
What should I put in after the line.split to assign the keys and values as a str and list of str?
To focus on your code and what you are doing wrong.
You are pretty much in an infinite loop with your while ';;;' not in line. So, you want to change your logic with how you are trying to insert data in to your dictionary. Simply use a conditional statement to check if ';;;' is in your line.
Then, when you get your key and value from your line.strip().split(' ') you simply just assign it to your dictionary as d[key] = val. However, you want a list, and val is currently a string at this point, so call split on val as well.
Furthermore, you do not need to have parentheses around key and val. It provides unneeded noise to your code.
The end result will give you:
d = {}
with open('new_file.txt') as f:
for line in f:
if ';;;' not in line:
key, val = line.strip().split(' ')
d[key] = val.split()
print(d)
Using your sample input, output is:
{'C': ['3', '4', '5'], 'A': ['1', '2', '3'], 'B': ['2', '3', '4']}
Finally, to provide an improvement to the implementation as it can be made more Pythonic. We can simplify this code and provide a small improvement to split more generically, rather than counting explicit spaces:
with open('new_file.txt') as fin:
valid = (line.split(None, 1) for line in fin if ';;;' not in line)
d = {k:v.split() for k, v in valid}
So, above, you will notice our split looks like this: split(None, 1). Where we are providing a maxsplit=1.
Per the docstring of split, it explains it pretty well:
Return a list of the words in S, using sep as the
delimiter string. If maxsplit is given, at most maxsplit
splits are done. If sep is not specified or is None, any
whitespace string is a separator and empty strings are
removed from the result.
Finally, we simply use a dictionary comprehension to obtain our final result.
Why not simply:
def make_dict(f_name):
with open(f_name) as f:
d = {k: v.split()
for k, v in [line.strip().split(' ')
for line in f
if ';;;' not in line]}
return d
Then
>>> print(make_dict('file_name'))
{'A': ['1', '2', '3'], 'B': ['2', '3', '4'], 'C': ['3', '4', '5']}

Using a dictionary to replace characters in a list of strings

I have the following dictionary:
clues = {'A': '#', 'N': '%', 'M': '*'}
I also have the following list:
puzzle = ['#+/084&"', '#3w#%#+', '8%203*','']
How can I replace the items from the list (i.e. by referencing the values from 'clues') with the keys in 'clues' so it would now appear the following way:
puzzle = ['A+/084&"', 'A3wANA+', '8N203M','']
Create a translation map from your dictionary, then use str.translate():
try:
# Python 3
maketrans = str.maketrans
except AttributeError:
# Python 2
from string import maketrans
m = maketrans(''.join(clues.values()), ''.join(clues))
result = [s.translate(m) for s in puzzle]
This does assume the values in clues are unique. str.translate() is by far the fastest method to map single characters to other single characters.
Demo (using Python 2.7):
>>> from string import maketrans
>>> clues = {'A': '#', 'N': '%', 'M': '*'}
>>> puzzle = ['#+/084&"', '#3w#%#+', '8%203*', '']
>>> m = maketrans(''.join(clues.values()), ''.join(clues))
>>> [s.translate(m) for s in puzzle]
['A+/084&"', 'A3wANA+', '8N203M', '']
You could do:
for key, value in clues.iteritems():
puzzle = [ a.replace(value,key) for a in puzzle]
To test it:
>>> clues = {'A': '#', 'N': '%', 'M': '*'}
>>> puzzle = ['#+/084&"', '#3w#%#+', '8%203*','']
>>> for key, value in clues.iteritems():
... puzzle = [ a.replace(value,key) for a in puzzle]
...
>>> puzzle
['A+/084&"', 'A3wANA+', '8N203M', '']
puzzle = ['#+/084&"', '#3w#%#+', '8%203*','']
clues = {'A': '#', 'N': '%', 'M': '*'}
answer = []
for p in puzzle:
for dest,src in clues.items():
p = p.replace(src,dest)
answer.append(d)

Categories