I want to remove consecutive "a" substrings and replace them with one "a" from a string without importing any packages.
For example, I want to get abbccca from aaabbcccaaaa.
Any suggestions?
Thanks.
This method will remove a determined repeated char from your string:
def remove_dulicated_char(string, char):
new_s = ""
prev = ""
for c in string:
if len(new_s) == 0:
new_s += c
prev = c
if c == prev and c == char:
continue
else:
new_s += c
prev = c
return new_s
print(remove_dulicated_char("aaabbcccaaaa", "a"))
Whats wrong with using a loop?
oldstring = 'aaabbcccaaaa'
# Initialise the first character as the same as the initial string
# as this will always be the same.
newstring = oldstring[0]
# Loop through each character starting at the second character
# check if the preceding character is an a, if it isn't add it to
# the new string. If it is an a then check if the current character
# is an a too. If the current character isn't an a then add it to
# the new string.
for i in range(1, len(oldstring)):
if oldstring[i-1] != 'a':
newstring += oldstring[i]
else:
if oldstring[i] != 'a':
newstring += oldstring[i]
print(newstring)
using python regular expressions this will do it.
If you don't know about regex. They are extremely powerful for
this kind of matching
import re
str = 'aaabbcccaaaa'
print(re.sub('a+', 'a', str))
You can use a function that removes double values of a string occurrence recursively until only one occurrence of the repeating string remains:
val = 'aaabbcccaaaaaaaaaaa'
def remove_doubles(v):
v = v.replace('aa', 'a')
if 'aa' in v:
v = remove_doubles(v)
if 'aa' in v:
v = remove_doubles(v)
else: return v
else: return v
print(remove_doubles(val))
There are many ways to do this. Here's another one:
def remove_duplicates(s, x):
t = [s[0]]
for c in s[1:]:
if c != x or t[-1] != x:
t.append(c)
return ''.join(t)
print(remove_duplicates('aaabbcccaaaa', 'a'))
Related
I'm trying to solve this exercise using enumerate, but I don't have any idea how to implement the value. In a mathematical way I said if for index and index+1 letter is the same do nothing, if the upcoming letter is different write letter. But I have no idea how to do it in python
Desired result aaabbbaas => abas.
def zad6(string):
b =""
for index,letter in enumerate(string):
if letter[index] == letter[index+1]:
b += None
else:
b += letter
return b
print(zad6("aaabbbaas"))
Here is a fix of your code using enumerate, you can check if each previous letter was the same, except the first time (index == 0):
def zad6(string):
for index, letter in enumerate(string):
if index == 0:
b = letter
elif letter != string[index-1]:
b += letter
return b
print(zad6("Baabba"))
output: 'Baba'
NB. this considers case, 'B' and 'b' will be different, if you want to ignore case use letter.lower() != string[index-1].lower()
alternative
just for the sake of showing an efficient solution, in real life you could use itertools.groupby:
from itertools import groupby
string = "Baabba"
''.join(l for l,_ in groupby(string))
Only append when you have something to append, there's no need to append None (and in fact, it doesn't work). Also, you should check if there's a next character at all in the string, or it will fail at the last iteration
def zad6(string):
b = ""
for index,letter in enumerate(string):
if index == len(string)-1 or letter != string[index+1]:
b+=letter
return b
print(zad6("Baabba"))
Here's an alternate approach without using a for loop, that seems a bit simpler:
from operator import itemgetter
def zad6(string):
filt = filter(lambda x: x[1] != string[x[0] - 1], enumerate(string))
return ''.join(map(itemgetter(1), filt))
assert zad6('aaabbbaas') == 'abas'
assert zad6('Baabba') == 'Baba'
I'm working on an assignment and have gotten stuck on a particular task. I need to write two functions that do similar things. The first needs to correct capitalization at the beginning of a sentence, and count when this is done. I've tried the below code:
def fix_capitalization(usrStr):
count = 0
fixStr = usrStr.split('.')
for sentence in fixStr:
if sentence[0].islower():
sentence[0].upper()
count += 1
print('Number of letters capitalized: %d' % count)
print('Edited text: %s' % fixStr)
Bu receive an out of range error. I'm getting an "Index out of range error" and am not sure why. Should't sentence[0] simply reference the first character in that particular string in the list?
I also need to replace certain characters with others, as shown below:
def replace_punctuation(usrStr):
s = list(usrStr)
exclamationCount = 0
semicolonCount = 0
for sentence in s:
for i in sentence:
if i == '!':
sentence[i] = '.'
exclamationCount += 1
if i == ';':
sentence[i] = ','
semicolonCount += 1
newStr = ''.join(s)
print(newStr)
print(semicolonCount)
print(exclamationCount)
But I'm struggling to figure out how to actually do the replacing once the character is found. Where am I going wrong here?
Thank you in advance for any help!
I would use str.capitalize over str.upper on one character. It also works correctly on empty strings. The other major improvement would be to use enumerate to also track the index as you iterate over the list:
def fix_capitalization(s):
sentences = [sentence.strip() for sentence in s.split('.')]
count = 0
for index, sentence in enumerate(sentences):
capitalized = sentence.capitalize()
if capitalized != sentence:
count += 1
sentences[index] = capitalized
result = '. '.join(sentences)
return result, count
You can take a similar approach to replacing punctuation:
replacements = {'!': '.', ';': ','}
def replace_punctuation(s):
l = list(s)
counts = dict.fromkeys(replacements, 0)
for index, item in enumerate(l):
if item in replacements:
l[index] = replacements[item]
counts[item] += 1
print("Replacement counts:")
for k, v in counts.items():
print("{} {:>5}".format(k, v))
return ''.join(l)
There are better ways to do these things but I'll try to change your code minimally so you will learn something.
The first function's issue is that when you split the sentence like "Hello." there will be two sentences in your fixStr list that the last one is an empty string; so the first index of an empty string is out of range. fix it by doing this.
def fix_capitalization(usrStr):
count = 0
fixStr = usrStr.split('.')
for sentence in fixStr:
# changed line
if sentence != "":
sentence[0].upper()
count += 1
print('Number of letters capitalized: %d' % count)
print('Edited text: %s' % fixStr)
In second snippet you are trying to write, when you pass a string to list() you get a list of characters of that string. So all you need to do is to iterate over the elements of the list and replace them and after that get string from the list.
def replace_punctuation(usrStr):
newStr = ""
s = list(usrStr)
exclamationCount = 0
semicolonCount = 0
for c in s:
if c == '!':
c = '.'
exclamationCount += 1
if c == ';':
c = ','
semicolonCount += 1
newStr = newStr + c
print(newStr)
print(semicolonCount)
print(exclamationCount)
Hope I helped!
Python has a nice build in function for this
for str in list:
new_str = str.replace('!', '.').replace(';', ',')
You can write a oneliner to get a new list
new_list = [str.replace('!', '.').replace(';', ',') for str in list]
You also could go for the split/join method
new_str = '.'.join(str.split('!'))
new_str = ','.join(str.split(';'))
To count capitalized letters you could do
result = len([cap for cap in str if str(cap).isupper()])
And to capitalize them words just use the
str.capitalize()
Hope this works out for you
I'm trying to write a function which given a string returns another string that flips its lowercase characters to uppercase and viceversa.
My current aproach is as follows:
def swap_case(s):
word = []
for char in s:
word.append(char)
for char in word:
if char.islower():
char.upper()
else:
char.lower()
str1 = ''.join(word)
However the string doesn't actually change, how should I alter the characters inside the loop to do so?
PS: I know s.swapcase() would easily solve this, but I want to alter the characters inside the string during a for loop.
def swap_case(s):
swapped = []
for char in s:
if char.islower():
swapped.append(char.upper())
elif char.isupper():
swapped.append(char.lower())
else:
swapped.append(char)
return ''.join(swapped)
you can use swapcase.
string.swapcase(s)
Return a copy of s, but with lower case letters converted to upper case and vice versa.
Source : Python docs
>>> name = 'Mr.Ed' or name= ["M","r",".","E","d"]
>>> ''.join(c.lower() if c.isupper() else c.upper() for c in name)
'mR.eD'
Your code is not working because you are not storing the chars after transforming them. You created a list with all chars and then, you access the values without actually saving them. Also, you should make your function return str1 or you will never get a result. Here's a workaround:
def swap_case(s):
word = []
for char in s:
if char.islower():
word.append(char.upper())
else:
word.append(char.lower())
str1 = ''.join(word)
return str1
By the way, I know you want to do it with a for loop, but you should know there are better ways to perform this which would be more pythonic.
You can use this code:
s = "yourString"
res = s.swapcase()
print(res)
Which will output:
YOURsTRING
def swap_case(s):
x = ''
for i in s:
if i.isupper():
i = i.lower()
else:
i = i.upper()
x += ''.join(i)
return x
does anyone know how to translate robber's languge to English in python?
like this one but in reverse?
def translate(s):
consonants = 'bcdfghjklmnpqrstvwxz'
return ''.join(a + 'o' + a if a in consonants else a for a in s)
print(translate("hej"))
Maybe something like:
def translate(s):
consonants = 'bcdfghjklmnpqrstvwxz'
counter = 0
outputcounter = 0
output = s
while counter < len(s):
char = s[counter]
if char in consonants:
output = output[:outputcounter] + char + output[outputcounter + 3:]
counter += 3
outputcounter += 1
else:
counter += 1
outputcounter += 1
return output
Try it out! (I don't know if that's nice code style, but however)
Here is an alternative approach
Since this is an interesting problem, I decided to have a go myself. Here is an efficient way of writing your first function with O(1) set lookup:
def translate_english_robber(s):
consonants = 'bcdfghjklmnpqrstvwxz'
# using a set instead is more efficient
lookup = set(consonants + consonants.upper())
result = ""
for char in s:
if char in lookup:
# anonymous function for converting the case of the letter "o"
convert_case = lambda x: "o" if x.islower() else "O"
# add it to the result
result += char + convert_case(char) + char
else:
result += char
return result
Then for the reverse translation, all you need to do is find a consonant, and append it to the list, then somehow remove the next 2 characters, and continue the next iteration after the last removed character. Otherwise, if the current character is not a constant, add it normally.
For example, If my Robbers language was "hohey", I would first find "h", add it, and remove "o" and "h" after that, then start iterating from "e". In the end, we would have "hey" as the English translation.
Using an iterator would be useful here. You can also read up on iterators here, they are quite useful for problems like this.
Here is my attempt:
def translate_robber_english(s):
consonants = 'bcdfghjklmnpqrstvwxz'
lookup = set(consonants + consonants.upper())
# create the iterator
it = iter(list(s))
result = ""
# loop till we reach the end
while True:
try:
# get the current letter
current = next(it)
# add it regardless
result += current
# if consonant, skip the next to letters
if current in lookup:
next(it)
next(it)
# If this exception occurs, break out of the loop
except StopIteration:
break
return result
And now you can get the reverse translations with both the above functions:
>>> robber = translate_english_robber("black")
>>> print(robber)
boblolacockok
>>> english = translate_robber_english(robber)
>>> print(english)
black
You can try something like this:
def reverse_translate(s):
vowel = ['a', 'e', 'i', 'o', 'u']
final = []
for i in range(len(s)):
if s[i] in vowel:
final.append(s[i])
else:
try:
if s[i] == s[i + 2]:
final.append(s[i:i + 3])
except IndexError:
pass
for j, i in enumerate(final):
if i == 'o':
try:
if final[j] == final[j + 1]:
pass
else:
del final[j]
except IndexError:
del final[j]
return "".join(list(map(lambda x: x[0], final)))
Now test_cases:
Normal test_case:
print(reverse_translate('boblolacockok'))
output:
black
But if text also include 'o' as vowel now :
print(reverse_translate('boblolocockok'))
output:
block
I have
import re
cadena = re.sub('[^0-9a-zA-Z]+', '', cadena)
how to remove non-alphanumeric characters except this
\ / # + -:, | #
Make sure to escape the backslash inside the character class. Use raw string for regular expression, it eliminates need in further escaping.
cadena = re.sub(r'[^0-9a-zA-Z\\/#+\-:,|#]+', '', cadena)
Please note that the underscore is considered an alphanumeric character. If you don't need to strip it, you can simplify the expression.
cadena = re.sub(r'[^\w\\/#+\-:,|#]+', '', cadena)
Example 1:
(Most easy way I think)
# String
string = 'ABC#790#'
# Remove the #, # and 7 from the string. (You can choose whatever you want to take out.)
line = re.sub('[##7]', '', string)
# Print output
print(line)
Example 2:
You can also make use of substrings, that way you can look on every position if a letter matches the letter you don't want in your string.
If the letter is one you would like to keep, you add that letter to a new string. Else you pass.
For example:
String 's' is your string, and string 'd' conatain letters you want to filter out.
s = 'abc/geG#gDvs#h81'
d = '##/'
e = ''
i = 0
j = 0
l = len(s)
g = len(d)
a = False
while i < l:
# Grab a single letter
letter1 = s[i:i+1]
# Add +1
i = i + 1
# Look if the letter is in string d
while j < g:
# Grab a single letter
letter2 = d[j:j+1]
# Add +1
j = j + 1
# Look if letter is not the same.
if (letter1 != letter2):
a = True
else:
a = False
break
# Reset j
j = 0
# Look if a is True of False.
# True: Letter does not contain letters from string d.
# False: Letter does contain letters from string d.
if (a == True):
e = e + letter1
else:
pass
# Print the result
print(e)