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

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

Related

python string replace using for loop with if else

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.

How to index list when there is 2 of the same char

I have been trying to make the even letters in a string become upper-cased and the odd letters to become lower-cased with a function, like so:
def myfunc('apple'):
#OUTPUTS: 'ApPlE'
This is what I made:
def myfunc(mystring):
stringList = [letter for letter in mystring]
for letter in stringList[1::2]:
stringList[stringList.index(letter)] = letter.lower()
for letter in stringList[::2]:
stringList[stringList.index(letter)] = letter.upper()
return ''.join(stringList)
I believe that, when I use words like 'apple' where there is two identical letters, the index() function can only manage to give me the index of the first 'p', if my word is apple.
It returns:
'APplE'
How could I fix this?
By iterating over the indices of the string, using the built-in function enumerate, together with the characters of the string (strings are also iterable):
def myfunc(mystring):
out = []
for i, c in enumerate(mystring):
if i % 2 == 0:
out.append(c.upper())
else:
out.append(c.lower())
return "".join(out)
Example output:
>>> myfunc('apple')
'ApPlE'
This is also a lot more efficient, since it only iterates over the string once. Your code iterates many times (each stringList.index call does a linear search for the letter).
If you want to make it a bit harder to read but re-use a bit more of what you already have, you can also use this, but I would not recommend it (as it iterates three times over the string, once to build the list and then twice to replace the characters):
def myfunc(mystring):
stringList = list(mystring)
stringList[::2] = map(str.upper, stringList[::2])
stringList[1::2] = map(str.lower, stringList[1::2])
return "".join(stringList)
The method list.index returns the index of the first occurence, making it unfit for recovering the index of the current element. Instead, you should use enumerate, this will allow you to get the expected result with a single list-comprehension.
def myFunc(s):
return ''.join([c.lower() if i % 2 else c.upper() for i, c in enumerate(s)])
print(myFunc('apple')) # ApPlE

Shift letters by a certain value in python

I had a coded text file that was coded by simple letter shifting. I have now gotten the information from it into two lists. In this format:
list_1 =['fjsir', 'vnjk', 'eioafnvjf', 'einbvfbj']
list_2 =[3,4,7,1]
The second list is by how many places in the alphabet should it move over. For eg. if index 0 in list one had 'fjsir' and it's corresponding index in list_2 is 3 then it would decode to 'cfpeo'. I'm not sure how I would match these in python.
To shift elements to the left:
chr(ord(char) - n)
Which uses ord() to get an integer representation of char, and substracts n from this number. It then uses chr() to convert it back to a character.
The function could look like this:
def shift(s, n):
return ''.join(chr(ord(char) - n) for char in s)
Which can get called nicely with zip():
list_1 =['fjsir', 'vnjk', 'eioafnvjf', 'einbvfbj']
list_2 =[3,4,7,1]
for x, y in zip(list_1, list_2):
print(shift(x, y))
And gives back the decodings:
cgpfo
rjfg
^bhZ_goc_
dhmaueai
Additionally, if you only want decodings to only consist of letters from the English alphabet, you can use a modulus function % instead:
def shift(s, n):
return ''.join(chr((ord(char) - 97 - n) % 26 + 97) for char in s)
Which gives back decodings with only letters:
cgpfo
rjfg
xbhtygocy
dhmaueai
Here is a simple solution:
alphabets = 'abcdefghijklmnopqrstuvwxyz'
list_1 = ['fjsir', 'vnjk', 'eioafnvjf', 'einbvfbj']
list_2 = [3,4,7,1]
final_list = []
for index,original_word in enumerate(list_1):
new_word = ''
for letter in original_word:
if letter in alphabets:
index_val = alphabets.index(letter) - list_2[index]
new_word += alphabets[index_val]
final_list.append(new_word)
print final_list
Output:
['cgpfo', 'rjfg', 'xbhtygocy', 'dhmaueai']
You can convert characters to number with ord() and convert numbers to characters with chr(). A shift function may look like:
def shift_string(inString, inOffset):
return "".join([chr(ord(x) + inOffset) for x in inString])
Accessing array elements from list is left to the reader. ;)
Note: This simple version will probably produce unwanted characters. You may simply use a modulo function to remain in the ASCII range.
def shift_string(inString, inOffset):
return "".join([chr(((ord(x) - ord(' ') + inOffset) % 95) + ord(' ')) for x in inString])
If your set of valid characters is more complex (e.g. letters), you should write a special function for the character transformation.

Counting the number of times a character in string1 is found in string2?

I'm trying to create a function which takes two strings and then returns the sum total of how many times every character in the first string is found in the second string under the condition that duplicate characters in the first are ignored.
e.g. search_counter('aabbaa','a') would mean a count of 1 since the the second string only has one a and no bs and we only want to search for a once despite there being four as.
Here's my attempt so far:
def search_counter(search_string, searchme):
count = 0
for x in search_string:
for y in searchme:
if x == y:
count = count + 1
return count
The problem with my example is that there is no check to ignore duplicate characters in search_string.
So instead of getting search_counter('aaa','a') = 1 I get 3.
for x in search_string:
You can get a list of characters without duplicates by converting the string to a set.
for x in set(search_string):
You can eliminate repetitions from a string by transforming it into a set:
>>> set("asdddd")
set(['a', 's', 'd'])
Preprocess your string this way, and the rest of the algorithm will remain the same (set objects are iterables, just like strings)
You can use iteration to do this
def search_counter(string, search):
count = 0
for i in range(len(string)):
count += string[i:].startswith(search)
return count
Or this one-liner
search_counter = lambda string, search: sum([string[i:].startswith(search) for i in range(len(string))])

need to count number of occurrences of given strings in an if statement

so in my function one of my if statements is that the string does not have more than 1 occurrence of a string that is in a list.
for example:
list = ['a','b']
i need to check if a string has more than one of those 2 characters in it or else it will move on to the next if statement.
s = 'aloha'
s will pass the if statement because b is not in s.
s = 'abcd'
s should fail this if statement because both a and b are in s.
more examples if it's not clear enough.
s = 'aaab'
this will fail the if statement and move on.
s = 'aaloh'
this will also fail
my if statement was:
if s.count('a') == 1 or s.count('b') == 1:
This if statement doesn't work
my question is, is there a way to check this without doing a for loop before hand?
You'll need a for loop, but you can still do it one line.
if sum(char in s for char in list) > 1:
If you wanted to look for specific numbers of a given character with some threshold, put your list of characters into a dict like d = {'a': 1, 'b': 4}.
if sum(s.count(char) >= count for char, count in d.items) > THRESHOLD:
Update
The OP commented that he wants a
a function that does something with the string if and only if that string doesn't have both 'a' and 'b' in the string. It can only have one of the two and not both and also only one occurrence of it.
Because OP's original post wanted to generalize 'a' and 'b' to a sequence of characters list, I interpret his meaning to be he wants an expression that returns True for a string s if and only if s has exactly one occurrence of exactly one element of a list of characters list.
sum(s.count(char) for char in list) <= 1
In OP's simple example, list = ['a', 'b'].

Categories