I'm trying to replace the characters of the reversed alphabet with those of the alphabet. This is what I've got:
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
rev_alphabet = alphabet[::-1]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
def f(alph, rev_alph):
return (alph, rev_alph)
char_list_of_tups = list(map(f, alphabet, rev_alphabet))
for alph, rev_alph in char_list_of_tups:
sample = sample.replace(rev_alph, alph)
print(sample)
expected output: did you see last night's episode?
actual output: wrw you svv ozst nrtst's vprsowv?
I understand that I'm printing the last "replacement" of the whole iteration. How can I avoid this without appending it to a list and then running into problems with the spacing of the words?
Your problem here is that you lose data as you perform each replacement; for a simple example, consider an input of "az". On the first replacement pass, you replace 'z' with 'a', and now have "aa". When you get to replacing 'a' with 'z', it becomes "zz", because you can't tell the difference between an already replaced character and one that's still unchanged.
For single character replacements, you want to use the str.translate method (and the not strictly required, but useful helper function, str.maketrans), to do character by character transliteration across the string in a single pass.
from string import ascii_lowercase # No need to define the alphabet; Python provides it
# You can use the original str form, no list needed
# Do this once up front, and reuse it for as many translate calls as you like
trans_map = str.maketrans(ascii_lowercase[::-1], ascii_lowercase)
sample = sample.translate(trans_map)
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
# or
alphabet = [chr(97 + i) for i in range(0,26)]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
res = []
for ch in sample:
if ch in alphabet:
res.append(alphabet[-1 - alphabet.index(ch)])
else:
res.append(ch)
print("".join(res))
Another Way if you are ok with creating a new string instead.
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
dictRev = dict(zip(alphabet, alphabet[::-1]))
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
s1="".join([dictRev.get(char, char) for char in sample])
print(s1)
"did you see last night's episode?"
Related
I have a list of symbols:
symbols_list = ['*','†','‡','§','¶','#']
and a longer list of elements as:
note_list = ['a','b','c','d'.....'z']
I want to join them in a dictionary to look like this:
{'*':'a','†':'b','‡':'c','§':'d','¶':'e','#':'f','**':'g','††':'h'...'***':'m'...etc. }
so basically the symbols_list values would repeat as *, **, ***, **** etc.
I tried to just get the symbols_list to be the same length at first using:
for a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a])
but it ended up doubling the elements each iteration instead of just adding one character each time
['*',
'†',
'‡',
'§',
'¶',
'#',
'**',
'††',
'‡‡',
'§§',
'¶¶',
'##',
'****',
'††††',
'‡‡‡‡',
'§§§§',
'¶¶¶¶',
'####',
'********',
'††††††††',
'‡‡‡‡‡‡‡‡',
'§§§§§§§§',
'¶¶¶¶¶¶¶¶',
'########',
'****************']
I thought it would be easier to make the symbols_list the same size first, and then combine them into a dictionary.
I couldn't resist trying to do it with itertools.
from itertools import chain, count
# yields *, †, ... **, ††, ... infinitely
symbol_generator = chain.from_iterable(((i*x for x in symbols_list) for i in count(1)))
{s:c for s,c in zip(symbol_generator, abc)}
{'*': 'a',
'†': 'b',
'‡': 'c',
'§': 'd',
'¶': 'e',
'#': 'f',
'**': 'g',
'††': 'h',
'‡‡': 'i',
'§§': 'j',
'¶¶': 'k',
'##': 'l',
'***': 'm',
'†††': 'n',
'‡‡‡': 'o',
'§§§': 'p',
'¶¶¶': 'q',
'###': 'r',
'****': 's',
'††††': 't',
'‡‡‡‡': 'u',
'§§§§': 'v',
'¶¶¶¶': 'w',
'####': 'x',
'*****': 'y',
'†††††': 'z'}
Maybe do it like this:
new_symbols_list = []
for i in range(len(note_list)//len(symbols_list)+1):
new_symbols_list += [k*(i+1) for k in symbols_list]
output = {s: l for s, l in zip(new_symbols_list[:len(note_list)], note_list)}
>>> output
{'*': 'a',
'†': 'b',
'‡': 'c',
'§': 'd',
'¶': 'e',
'#': 'f',
'**': 'g',
'††': 'h',
'‡‡': 'i',
'§§': 'j',
'¶¶': 'k',
'##': 'l',
'***': 'm',
'†††': 'n',
'‡‡‡': 'o',
'§§§': 'p',
'¶¶¶': 'q',
'###': 'r',
'****': 's',
'††††': 't',
'‡‡‡‡': 'u',
'§§§§': 'v',
'¶¶¶¶': 'w',
'####': 'x',
'*****': 'y',
'†††††': 'z'}
for a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a])
You append symbols_list[a]+symbols_list[a], which essentially doubles symbols_list[a]. You just want to add the first character of symbols_list[a] to itself, so do
for a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a][0])
Here is a oneliner:
{ (int(i/len(symbols_list))+1)*symbols_list[i%len(symbols_list)] : e for i, e in enumerate(note_list) }
I have a long list of words that I'm trying to go through and if the word contains a specific character remove it. However, the solution I thought would work doesn't and doesn't remove any words
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
validwords = []
for i in l3:
for x in firstchect:
if i not in x:
validwords.append(x)
continue
else:
break
If a word from firstcheck has a character from l3 I want it removed or not added to this other list. I tried it both ways. Can anyone offer insight on what could be going wrong? I'm pretty sure I could use some list comprehension but I'm not very good at that.
The accepted answer makes use of np.sum which means importing a huge numerical library to perform a simple task that the Python kernel can easily do by itself:
validwords = [w for w in firstcheck if all(c not in w for c in l3)]
you can use a list comprehension:
import numpy as np
[w for w in firstcheck if np.sum([c in w for c in l3])==0]
It seems all the words contain at least 1 char from l3 and the output of above is an empty list.
If firstcheck is defined as below:
firstcheck = ['a', 'z', 'poach', 'omnificent']
The code should output:
['a', 'z']
If you want to avoid all loops etc, you can use re directly.
import re
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['azz', 'poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
# Create a regex string to remove.
strings_to_remove = "[{}]".format("".join(l3))
validwords = [x for x in firstcheck if re.sub(strings_to_remove, '', x) == x]
print(validwords)
Output:
['azz']
Ah, there was some mistake in code, rest was fine:
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['aza', 'ca', 'poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
validwords = []
flag=1
for x in firstcheck:
for i in l3:
if i not in x:
flag=1
else:
flag=0
break
if(flag==1):
validwords.append(x)
print(validwords)
So, here the first mistake was, the for loops, we need to iterate through words first then, through l3, to avoid the readdition of elements.
Next, firstcheck spelling was wrong in 'for x in firstcheck` due to which error was there.
Also, I added a flag, such that if flag value is 1 it will add the element in validwords.
To, check I added new elements as 'aza' and 'ca', due to which, now it shows correct o/p as 'aza' and 'ca'.
Hope this helps you.
I am trying to remove certain characters from a string. My way of going about it is to turn the string into a list, iterate through each list and append each good character to a new list and return that new list but for some reason, it doesn't do that. This is the input:
"4193 with words"
and this is the output:
4193withwords
In other words, the only part of the code which works is the part of removing the whitespaces. Here is my entire code:
class Solution:
def myAtoi(self, str: str) -> int:
illegal_char = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '#', '#', '$', '%', '^', '&' '*', '(', ')', '=', '+', '[', ']', '{', '}', '|']
new_list = []
integer_list = list(str)
for i in range(len(integer_list)):
if integer_list[i] != any(illegal_char):
new_list.append(integer_list[i])
output = ''.join(new_list)
output = output.replace(' ', '')
return output
You can do a join on a list-comprehension. What you need is a membership check in list and form string with only those characters you need:
''.join([x for x in s if x not in illegal_char]).replace(' ', '')
Note that I have renamed your string to s, because str is a built-in.
Also to add, if you can include space as illegal_char you can avoid replace at the end.
Hmm, this is a very complicated way of replacing some characters. I suggest you, to learn some regex, as it could help you alot. There is a regex library for python called re.
This would be my solution:
import re
mytext = "4193 with words"
newtext = re.sub("\s", "", mytext)
I have a string of words and I want to separate them into individual characters. However, if a group of characters is part of what I've called "special consonant pairs", they need to remain together.
These are some of my "special consonant pairs":
consonant_pairs = ["ng", "ld", "dr", "bl", "nd", "th" ...]
This is one of the sample strings I want to separate into characters:
sentence_1 = "We were drinking beer outside and we could hear the wind blowing"
And this would be my desired output (I have already deleted spaces and punctuation):
sentence_1_char = ['w', 'e', 'w', 'e', 'r', 'e', 'dr', 'i', 'n', 'k', 'i', 'ng', 'b', 'e', 'e', 'r', 'o', 'u', 't', 's', 'i', 'd', 'e', 'a', 'n', 'd', 'w', 'e', 'c', 'o', 'u', 'ld', 'h', 'e', 'a', 'r', 'th', 'e', 'w', 'i', 'nd', 'bl', 'o', 'w', 'i', 'ng']
I thought of using list(), though I don't know how to go about the consonant pairs. Could anyone help me?
A quick (not necessarily performant) answer:
import re
charred = re.split('(' + '|'.join(consonant_pairs) + ')', sentence)
EDIT: To get the expected output in OP:
import re
matches = re.finditer('(' + '|'.join(consonant_pairs) + '|.)', sentence)
charred = [sentence[slice(*x.span())] for x in matches]
from random import choice
print ("Enigma")
list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
range (0,25)
cha2 = choice(list)
complete = choice(list)
for x in range (0, 90000):
("Type alphabet")
cha1=input()
print (complete)
When I run it and input an alphabet the same alphabet outputs as the first time. However I want it to output a different random alphabet each time I enter an alphabet. Thanks
Chris_Rands has it right in the comments...
complete = choice(list) is the line that choose a letter to return, and you are only running it one time. If you wanted it to run every time, you need to put it inside your while loop:
from random import choice
print ("Enigma")
list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
for x in range (0, 90000):
("Type alphabet")
cha1=input()
complete = choice(list) # This is the key change here
print (complete)
To answer: "I want it to output a different random alphabet each time I enter an alphabet"
From the above, you will check cha1 against the complete, and while they are the same, keep calling choice to update
cha1=input()
complete = choice(list)
while cha1 == complete:
complete = choice(list)