python string replace using for loop with if else - python

I am new with python, trying to replace string using for loop with if else condition,
I have a string and want to replace some character of that string in a such way that it should take / pick first character of the string and search them in the old_list if the character match it should replace that character with the character of new_list and if the character does not match it should consider that character (previous) and the next character together of the string and search them combinely and again search in old_list and so on.
it should replace in this oder (picking the character from string) = 010,101,010,010,100,101,00,00,011,1101,011,00,101,010,00,011,1111,1110,00,00,00,010,101,010,
replacing value = 1001,0000,0000,1000,1111,1001,1111,1111,100,1010101011,100,1111,1001,0000,1111,100,10100101,101010,1111,1111,1111,0000,1001,
with the example of above string if we performed that operation the string will becomes
final or result string = 10010000000010001111100111111111100101010101110011111001000011111001010010110101011111111111100001001
string = 01010101001010010100000111101011001010100001111111110000000010101010
old_list = ['00','011','010','101','100','1010','1011','1101','1110','1111']
new_list = ['1111','100','0000','1001','1000'1111','0101','1010101011','101010','10100101']
i = 0
for i in range((old), 0):
if i == old:
my_str = my_str.replace(old[i],new[i], 0)
else:
i = i + 1
print(my_str)
as result, string become = 10010000000010001111100111111111100101010101110011111001000011111001010010110101011111111111100001001

new = ['a ','local ','is ']
my_str = 'anindianaregreat'
old = ['an','indian','are']
for i, string in enumerate(old):
my_str = my_str.replace(string, new[i], 1)
print(my_str)

Your usage of range is incorrect.
range goes from lower (inclusive) to higher (exclusive) or simply 0 to higher (exclusive)
Your i == old condition is incorrect as well. (i is an integer, while old is a list). Also what is it supposed to do?
You can simply do:
for old_str, new_str in zip(old, new):
my_str = my_str.replace(old_str, new_str, 1)
https://docs.python.org/3/library/stdtypes.html#str.replace
You can provide an argument to replace to specify how many occurrences to replace.
No conditional is required since if old_str is absent, nothing will be replaced anyway.

Related

How can I change numbers to a letter in a string?

I'm trying to change numbers in a string to an assigned letter (0 would be 'A', 1 => 'B' and so on...).
In this case I must use a function (def) to change the numbers to the assigned letter. I tried doing the program with if's in a for cycle with indices and it worked, but apperantly there is an easier and shorter solution. I tried doing it with isdigit() instead, but my function doesn't recognize the numbers in the given word and just prints out the same word
You can use a dictionary to map digits to letters, write a generator to get those letters and join it all into a resultant string. The dictionary's get method either gets the value or returns a default. Use this to return any non-digit characters.
>>> digit_map = dict(zip('123456789', 'ABCDEFGHI'))
>>> test = 'a1b2c3'
>>> "".join(digit_map.get(c,c) for c in test)
'aAbBcC'
Use ord to get the numeric value of a character, and chr to turn the numeric value back into a character. That lets you convert a number like 1 into its offset from another character.
Then use join to put it all together:
>>> ''.join(chr(int(c)+ord('A')) if c.isdecimal() else c for c in 'a1b2c3')
'aBbCcD'
One solution would be creating an array that would store each letter as a string as such:
alphabet = ["A", "B", "C"] // and so on
Then you could loop trough the string and find all numbers, then for each numbers get the corresponding letter by accessing it from the array as such py alphabet[i] and feed it back to the string and return that
Here is a simple function that you can use to convert numbers to letters in a given string:
def convert_numbers_to_letters(s):
# Create a dictionary that maps numbers to letters
number_to_letter = {str(i): chr(i + ord('A')) for i in range(10)}
# Iterate through each character in the string
result = ""
for c in s:
# If the character is a number, convert it to a letter
if c.isdigit():
result += number_to_letter[c]
# Otherwise, just add the character to the result
else:
result += c
return result

Python: Is there a way to find and remove the first and last occurrence of a character in a string?

The problem:
Given a string in which the letter h occurs at least twice.
Remove from that string the first and the last occurrence of
the letter h, as well as all the characters between them.
How do I find the first and last occurrence of h? And how can I remove them and the characters in between them?
#initialize the index of the input string
index_count =0
#create a list to have indexes of 'h's
h_indexes = []
#accept input strings
origin_s = input("input:")
#search 'h' and save the index of each 'h' (and save indexes of searched 'h's into h_indexes
for i in origin_s:
first_h_index =
last_h_index =
#print the output string
print("Output:"+origin_s[ : ]+origin_s[ :])
Using a combination of index, rindex and slicing:
string = 'abc$def$ghi'
char = '$'
print(string[:string.index(char)] + string[string.rindex(char) + 1:])
# abcghi
You need to use regex:
>>> import re
>>> s = 'jusht exhamplhe'
>>> re.sub(r'h.+h', '', s)
'juse'
How do I find the first and last occurrence of h?
First occurence:
first_h_index=origin_s.find("h");
Last occurence:
last_h_index=origin_s.rfind("h");
And how can I remove them and the characters in between them?
Slicing
string = '1234-123456789'
char_list = []
for i in string:
char_list.append(string[i])
char_list.remove('character_to_remove')
According to the documentation, remove(arg) is a method acting on a mutable iterable (for example list) that removes the first instance of arg in the iterable.
This will help you to understand more clearly:
string = 'abchdef$ghi'
first=string.find('h')
last=string.rfind('h')
res=string[:first]+string[last+1:]
print(res)

Remove punctuation items from end of string

I have a seemingly simple problem, which I cannot seem to solve. Given a string containing a DOI, I need to remove the last character if it is a punctuation mark until the last character is letter or number.
For example, if the string was:
sampleDoi = "10.1097/JHM-D-18-00044.',"
I want the following output:
"10.1097/JHM-D-18-00044"
ie. remove .',
I wrote the following script to do this:
invalidChars = set(string.punctuation.replace("_", ""))
a = "10.1097/JHM-D-18-00044.',"
i = -1
for each in reversed(a):
if any(char in invalidChars for char in each):
a = a[:i]
i = i - 1
else:
print (a)
break
However, this produces 10.1097/JHM-D-18-00 but I would like it to produce 10.1097/JHM-D-18-00044. Why is the 44 removed from the end?
The string function rstrip() is designed to do exactly this:
>>> sampleDoi = "10.1097/JHM-D-18-00044.',"
>>> sampleDoi.rstrip(",.'")
'10.1097/JHM-D-18-00044'
Corrected code:
import string
invalidChars = set(string.punctuation.replace("_", ""))
a = "10.1097/JHM-D-18-00044.',"
i = -1
for each in reversed(a):
if any(char in invalidChars for char in each):
a = a[:i]
i = i # Well Really this line can just be removed all together.
else:
print (a)
break
This gives the output you want, while keeping the original code mostly the same.
This is one way using next and str.isalnum with a generator expression utilizing enumerate / reversed.
sampleDoi = "10.1097/JHM-D-18-00044.',"
idx = next((i for i, j in enumerate(reversed(sampleDoi)) if j.isalnum()), 0)
res = sampleDoi[:-idx]
print(res)
'10.1097/JHM-D-18-00044'
The default parameter 0is used so that, if no alphanumeric character is found, an empty string is returned.
If you dont wanna use regex:
the_str = "10.1097/JHM-D-18-00044.',"
while the_str[-1] in string.punctuation:
the_str = the_str[:-1]
Removes the last character until it's no longer a punctuation character.

strings match after a certain character

I wanted to see if two strings matched each other after the last time a certain character appears. For example:
same_list = ['Time - is an illusion.', 'Lunchtime - which is delicious - is an illusion.']
True
So in this case my certain character is '-'. I want to see if the string after the last '-' for both strings match each other. The string after '-' is 'is an illusion.' for both strings. Therefore it is true.
So far I have:
same_list = ['Time - is an illusion.', 'Lunchtime - which is delicious - is an illusion.']
some_list = []
for string in same_list:
for ch in string:
if ch == '-':
new_string = string.split(ch)
some_list.append(new_string)
i = 0
for sublist[-1] in some_list:
I feel like I'm forgetting an easier way of doing this in python. All I can remember is the while loop, but that would return the first occurrence of '-', not the last. Also, the function I have written returns the second string twice as it was split twice. How do I get rid of that?
You can do something simple like this (assuming that all endings in a list must match):
def end_matches(*phrases): # phrases becomes a tuple that will take any number
phrase_endings = set() # number of positional parameters
for phrase in phrases:
end = phrase.split('-')[-1] # take the last element of the split list
phrase_endings.add(end)
return len(phrase_endings) == 1 # the set holds only unique values, so a set of
# length 1 means all values in the set are the same
You can now test it out:
>>> same_list = ['Time - is an illusion.', 'Lunchtime - which is delicious - is an illusion.']
>>> end_matches(*same_list) # unpack the list into individual positional arguments
True

String manipulation weirdness when incrementing trailing digit

I got this code:
myString = 'blabla123_01_version6688_01_01Long_stringWithNumbers'
versionSplit = re.findall(r'-?\d+|[a-zA-Z!##$%^&*()_+.,<>{}]+|\W+?', myString)
for i in reversed(versionSplit):
id = versionSplit.index(i)
if i.isdigit():
digit = '%0'+str(len(i))+'d'
i = int(i) + 1
i = digit % i
versionSplit[id]=str(i)
break
final = ''
myString = final.join(versionSplit)
print myString
Which suppose to increase ONLY the last digit from the string given. But if you run that code you will see that if there is the same digit in the string as the last one it will increase it one after the other if you keep running the script. Can anyone help me find out why?
Thank you in advance for any help
Is there a reason why you aren't doing something like this instead:
prefix, version = re.match(r"(.*[^\d]+)([\d]+)$", myString).groups()
newstring = prefix + str(int(version)+1).rjust(len(version), '0')
Notes:
This will actually "carry over" the version numbers properly: ("09" -> "10") and ("99" -> "100")
This regex assumes at least one non-numeric character before the final version substring at the end. If this is not matched, it will throw an AttributeError. You could restructure it to throw a more suitable or specific exception (e.g. if re.match(...) returns None; see comments below for more info).
Adjust accordingly.
The issue is the use of the list.index() function on line 5. This returns the index of the first occurrence of a value in a list, from left to right, but the code is iterating over the reversed list (right to left). There are lots of ways to straighten this out, but here's one that makes the fewest changes to your existing code: Iterate over indices in reverse (avoids reversing the list).
for idx in range(len(versionSplit)-1, -1, -1):
i = versionSplit[idx]
if chunk.isdigit():
digit = '%0'+str(len(i))+'d'
i = int(i) + 1
i = digit % i
versionSplit[idx]=str(i)
break
myString = 'blabla123_01_version6688_01_01veryLong_stringWithNumbers01'
versionSplit = re.findall(r'-?\d+|[^\-\d]+', myString)
for i in xrange(len(versionSplit) - 1, -1, -1):
s = versionSplit[i]
if s.isdigit():
n = int(s) + 1
versionSplit[i] = "%0*d" % (len(s), n)
break
myString = ''.join(versionSplit)
print myString
Notes:
It is silly to use the .index() method to try to find the string. Just use a decrementing index to try each part of versionSplit. This was where your problem was, as commented above by #David Robinson.
Don't use id as a variable name; you are covering up the built-in function id().
This code is using the * in a format template, which will accept an integer and set the width.
I simplified the pattern: either you are matching a digit (with optional leading minus sign) or else you are matching non-digits.
I tested this and it seems to work.
First, three notes:
id is a reserved python word;
For joining, a more pythonic idiom is ''.join(), using a literal empty string
reversed() returns an iterator, not a list. That's why I use list(reversed()), in order to do rev.index(i) later.
Corrected code:
import re
myString = 'blabla123_01_version6688_01_01veryLong_stringWithNumbers01'
print myString
versionSplit = re.findall(r'-?\d+|[a-zA-Z!##$%^&*()_+.,<>{}]+|\W+?', myString)
rev = list(reversed(versionSplit)) # create a reversed list to work with from now on
for i in rev:
idd = rev.index(i)
if i.isdigit():
digit = '%0'+str(len(i))+'d'
i = int(i) + 1
i = digit % i
rev[idd]=str(i)
break
myString = ''.join(reversed(rev)) # reverse again only just before joining
print myString

Categories