multiplying letter of string by digits of number - python

I want to multiply letter of string by digits of number. For example for a word "number" and number "123"
output would be "nuummmbeerrr". How do I create a function that does this? My code is not usefull, because it doesn't work.
I have only this
def new_word(s):
b=""
for i in range(len(s)):
if i % 2 == 0:
b = b + s[i] * int(s[i+1])
return b
for new_word('a3n5z1') output is aaannnnnz .

Using list comprehension and without itertools:
number = 123
word = "number"
new_word = "".join([character*n for (n, character) in zip(([int(c) for c in str(number)]*len(str(number)))[0:len(word)], word)])
print(new_word)
# > 'nuummmbeerrr'
What it does (with more details) is the following:
number = 123
word = "number"
# the first trick is to link each character in the word to the number that we want
# for this, we multiply the number as a string and split it so that we get a list...
# ... with length equal to the length of the word
numbers_to_characters = ([int(c) for c in str(number)]*len(str(number)))[0:len(word)]
print(numbers_to_characters)
# > [1, 2, 3, 1, 2, 3]
# then, we initialize an empty list to contain the repeated characters of the new word
repeated_characters_as_list = []
# we loop over each number in numbers_to_letters and each character in the word
for (n, character) in zip(numbers_to_characters, word):
repeated_characters_as_list.append(character*n)
print(repeated_characters_as_list)
# > ['n', 'uu', 'mmm', 'b', 'ee', 'rrr']
new_word = "".join(repeated_characters_as_list)
print(new_word)
# > 'nuummmbeerrr'

This will solve your issue, feel free to modify it to fit your needs.
from itertools import cycle
numbers = cycle("123")
word = "number"
output = []
for letter in word:
output += [letter for _ in range(int(next(numbers)))]
string_output = ''.join(output)
EDIT:
Since you're a beginner This will be easier to understand for you, even though I suggest reading up on the itertools module since its the right tool for this kind of stuff.
number = "123"
word = "number"
output = []
i = 0
for letter in word:
if(i == len(number)):
i = 0
output += [letter for _ in range(int(number[i]))]
i += 1
string_output = ''.join(output)
print(string_output)

you can use zip to match each digit to its respective char in the word (using itertools.cycle for the case the word is longer), then just multiply the char by that digit, and finally join to a single string.
try this:
from itertools import cycle
word = "number"
number = 123
number_digits = [int(d) for d in str(number)]
result = "".join(letter*num for letter,num in zip(word,cycle(number_digits)))
print(result)
Output:
nuummmbeerrr

Related

Comparing the Nth letter to Nth letters of multiple strings in python

I can't quite figure this one out.
I have multiple five letter long strings and I want to compare each of the letters of the strings to a single string, and then to know if any of the Nth letters of the strings are equal to the Nth letter of the string I'm comparing them to, like this:
string_1 = 'ghost'
string_2 = 'media'
string_3 = 'blind'
the_word = 'shine'
if the_word[0] == string_1[0] or the_word[0] == string_2[0] or the_word[0] == string_3[0] or the_word[1] == string_1[1] or the_word[1] == string_2[1]... and so on...
print('The Nth letter of some of the strings is equal to the Nth letter of the_word')
else:
print('None of the letters positions correspond')
If there are multiple strings I want to compare the if statement gets very long so there must be a better way of doing this.
I would also like to know what the corresponding letters are (in this case they would be H (string_1[1] == the_word[1]), I (string_3[2] == the_word[2]) and N (string_3[3] == the_word[3])
If there are more than one corresponding letters I would like the return to be list containing all of the letters.
Also I dont need to know if the corresponding letter was the first or whatever the letters position in the word is, only if there are any (and what) corresponding letters.
I find this kind of hard to explain so sorry for possible confusion, will be happy to elaborate.
Thank you!
IIUC, you can get to what you want using zip -
base_strings = zip(string_1, string_2, string_3)
for cmp_pair in zip(the_word, base_strings):
if (cmp_pair[0] in cmp_pair[1]):
print(cmp_pair[0])
Output
h
i
n
You can extract the logic to a dedicated function and call it over each character of the string to be checked:
string_1 = 'ghost'
string_2 = 'media'
string_3 = 'blind'
the_word = 'shine'
def check_letter(l, i, words):
match = []
for w in words:
if w[i] == l:
match.append(w)
return match
for i in range(len(the_word)):
l = the_word[i]
print("checking letter: {}".format(l))
match = check_letter(l, i, [string_1, string_2, string_3])
if (len(match) > 0):
print("found in: {}".format(match))
else:
print("found in: -")
The above code results in:
$ python3 test.py
checking letter: s
found in: -
checking letter: h
found in: ['ghost']
checking letter: i
found in: ['blind']
checking letter: n
found in: ['blind']
checking letter: e
found in: -
Maybe this answers your question:
strings = ['ghost', 'media', 'blind']
the_word = 'shine'
for s in strings:
check = []
lett = []
for i in range(len(s)):
if s[i] == the_word[i]:
check.append(i)
lett.append(s[i])
if check:
print('The letters {0} (position {1}) of the string {2} match to
the word {3}'.format(lett,check,s,the_word))
else:
print('No match between {0} and {1}'.format(s,the_word))
Well one straight forward way would be the following:
string_1 = 'ghost'
string_2 = 'media'
string_3 = 'blind'
string_4 = 'trenn'
the_word = 'shine'
string_list = [string_1, string_2, string_3]
duplicate_letters_list = []
for string in string_list:
for i in range(5):
if the_word[i] == string[i]:
print(f'{i}th letter is in {string} is a duplicate')
if the_word[i] not in duplicate_letters_list:
duplicate_letters_list.append(the_word[i])
print(duplicate_letters_list)
Output
1th letter is in ghost is a duplicate
2th letter is in blind is a duplicate
3th letter is in blind is a duplicate
['h', 'i', 'n']

split a string to have chunks containing the maximum number of possible characters

e.g. string = 'bananaban'
=> ['ban', 'anab', 'an']
My attempt:
def apart(string):
letters = []
for i in string:
while i not in letters:
letters.append(i)
print("The letters are:" +str(letters))
x = []
result = []
return result
string = str(input("Enter string: "))
print(apart(string)
Basically, If I know all the letters that are in the word/string, I want to add them into x, until x contains all letters. Then I want to add x into result.
In my examaple "bananaban" it would mean [ban] is one x, because "ban" countains the letter "b","a" and "n". Same goes for [anab]. [an] only contains "a" and "n" because it is the end of the word.
Would be cool if somebody could help me ^^
IIUC, you want to split after all characters are in the current chunk.
You could use a set to keep track of the seen characters:
s = 'bananaban'
seen = set()
letters = set(s)
out = ['']
for c in s:
if seen != letters:
out[-1] += c
seen.add(c)
else:
seen = set(c)
out.append(c)
output: ['ban', 'anab', 'an']
The logical way seens to be first create a set with all letters in your string, then go over teh original one, collecting each character, and startign a new collection each time the set of letters in the collection match the original.
def apart(string):
target = set(string)
result = []
component = ""
for char in string:
component += char
if set(component) == target:
result.append(component)
component = ""
if component:
result.append(component)
return result
Using a set of the characters in the string, you can loop through the string and add or extend the last group in your resulting list:
S = "bananaban"
chars = set(S) # distinct characters of string
groups = [""] # start with an empty group
for c in S:
if chars.issubset(groups[-1]): # group contains all characters
groups.append(c) # start a new group
else:
groups[-1] += c # append character to last group
print(groups)
['ban', 'anab', 'an']

Shifting all the alphabets of a string by a certain step

input: ['baNaNa', 7] # string and step size
required output : 'utGtGt' # every character of string shifted backwards by step size
import ast
in_string = input()
lis = ast.literal_eval(in_string)
st = lis[0]
step = lis[1]
alphabets = 'abcdefghijklmnopqrstuvwxyz'
password = ''
for letter in st:
if letter in alphabets:
index_val = alphabets.index(letter) - (step)
password += alphabets[index_val]
print(password)
Output i am getting is 'utgtgt'. I want 'utGtGt'. Help on this would be appreciated a lot.
The string module has methods to create a transformation dictionary and a translate method to do exactly what you want:
st = "baNaNa"
step = 7
alphabets = 'abcdefghijklmnopqrstuvwxyz'
alph2 = alphabets.upper()
# lower case translation table
t = str.maketrans(alphabets, alphabets[-step:]+alphabets[:-step])
# upper case translation table
t2 = str.maketrans(alph2, alph2[-step:]+alph2[:-step])
# merge both translation tables
t.update(t2)
print(st.translate(t))
Output:
utGtGt
You give it the original string and an equal long string to map letters to and apply that dictionary using str.translate(dictionary).
The sliced strings equate to:
print(alphabets)
print(alphabets[-step:]+alphabets[:-step])
abcdefghijklmnopqrstuvwxyz
tuvwxyzabcdefghijklmnopqrs
which is what your step is for.
See Understanding slice notation if you never saw string slicing in use.
by processing each charater and checking it's cardinal no and making calculation accordingly help you to reach the result
def func(string, size):
if size%26==0:
size=26
else:
size=size%26
new_str = ''
for char in string:
if char.isupper():
if ord(char)-size<ord('A'):
new_str+=chr(ord(char)-size+26)
else:
new_str+=chr(ord(char)-size)
elif char.islower():
if ord(char)-size<ord('a'):
new_str+=chr(ord(char)-size+26)
else:
new_str+=chr(ord(char)-size)
return new_str
res =func('baNaNa', 7)
print(res)
# output utGtGt
Here's a simple solution that makes use of the % modulo operator to shift letters backwards.
It basically collects all of the letters in a reverse index lookup dictionary, so looking up letter positions is O(1) instead of using list.index(), which is linear O(N) lookups.
Then it goes through each letter and calculates the shift value from the letter index e.g. for the letter a with a shift value of 7, the calculation will be (0 - 7) % 26, which will give 19, the position of u.
Then once you have this shift value, convert it to uppercase or lowercase depending on the case of the original letter.
At the end we just str.join() the result list into one string. This is more efficient than doing += to join strings.
Demo:
from string import ascii_lowercase
def letter_backwards_shift(word, shift):
letter_lookups = {letter: idx for idx, letter in enumerate(ascii_lowercase)}
alphabet = list(letter_lookups)
result = []
for letter in word:
idx = letter_lookups[letter.lower()]
shifted_letter = alphabet[(idx - shift) % len(alphabet)]
if letter.isupper():
result.append(shifted_letter.upper())
else:
result.append(shifted_letter.lower())
return ''.join(result)
Output:
>>> letter_backwards_shift('baNaNa', 7)
utGtGt
I would probably go with #Patrick Artner's pythonic solution. I just showed the above implementation as a learning exercise :-).

Deleting adjacent repeating characters in a string

I want to delete adjacent repeating characters in a string in Python 3. For ex if the input is AABBC the output is ABC or if the input is AAABBBCC the output is ABC. I made two attempts to solve this problem.
Attempt #1
string = input()
for i in range (len(string) - 1):
if string[i] == string[i+1]:
string.replace(string[i],"")
print(string)
The above code returns the same string that is entered. If I enter AABBC it simply returns the same string. Not knowing what I was doing wrong, I tried another attempt.
Attempt #2
string = input()
new = []
for i in string:
new.append(i)
for i in range (len(new) - 3):
"""in the above line, if I set the range to (len(new)-2), it gives me an
error saying "list index out of range"."""
if new[i] == new[i+1]:
new.pop(i)
print(new)
The above code works for double repeating characters, but fails when there are 3 or more repeating characters. If I input AABBC it returns the list ['A','B','C'] which is perfectly fine, but with the input AAABBCC it returns ['A', 'A', 'B', 'C'].
Using Regex:
import re
s = ["AABBC", "AAABBBCC"]
for i in s:
print( re.sub(r"(.)\1+", r"\1", i) )
Or:
s = ["AABBC", "AAABBBCC"]
for i in s:
temp = []
for j in i:
if not temp:
temp.append(j)
else:
if temp[-1] != j:
temp.append(j)
print("".join(temp))
Output:
ABC
ABC
You can use itertools to group the characters like,
>>> import itertools
>>> [x[0] for x in itertools.groupby('AABBCC')]
['A', 'B', 'C']
string = 'AAABBBCC'
result = ''
for letter in string:
if len(result) > 0:
if result[-1] != letter: # [-1] is the last letter
result += letter
else:
result = letter # the first letter will always be included
print(result) # ABC
That is, only append the letter if it is not already at the end of the result string.
An easy to understand short solution :
mot = 'AABBBCC'
a = [mot[0]] + [mot[i] if mot[i]!=mot[i-1] else '' for i in range(1, len(mot))]
>>> ['A', '', 'B', '', '', 'C', '']
result = ''
for lettre in a:
result += lettre
result
>>> 'ABC'
You first create a list of the letters which respects a certain condition, then you convert this list into a string. This algorithm can be used for many different conditions.
Note that you don't need to import any new library.

Using a For Loop to Change Words in Strings to List Items

I am trying to use a for loop to find every word in a string that contains exactly one letter e.
My guess is that I need to use a for loop to first separate each word in the string into its own list (for example, this is a string into ['this'], ['is'], ['a'], ['string'])
Then, I can use another For Loop to check each word/list.
My string is stored in the variable joke.
I'm having trouble structuring my For Loop to make each word into its own list. Any suggestions?
j2 = []
for s in joke:
if s[0] in j2:
j2[s[0]] = joke.split()
else:
j2[s[0]] = s[0]
print(j2)
This is a classic case for list comprehensions. To generate a list of words containing exactly one letter 'e', you would use the following source.
words = [w for w in joke.split() if w.count('e') == 1]
For finding words with exactly one letter 'e', use regex
import re
mywords = re.match("(\s)*[e](\s)*", 'this is your e string e')
print(mywords)
I would use Counter:
from collections import Counter
joke = "A string with some words they contain letters"
j2 = []
for w in joke.split():
d = Counter(w)
if 'e' in d.keys():
if d['e'] == 1:
j2.append(w)
print(j2)
This results in:
['some', 'they']
A different way to do it using numpy which is all against for:
s = 'Where is my chocolate pizza'
s_np = np.array(s.split())
result = s_np[np.core.defchararray.count(s_np, 'e').astype(bool)]
This is one way:
mystr = 'this is a test string'
[i for i in mystr.split() if sum(k=='e' for k in i) == 1]
# test
If you need an explicit loop:
result = []
for i in mystr:
if sum(k=='e' for k in i) == 1:
result.append(i)
sentence = "The cow jumped over the moon."
new_str = sentence.split()
count = 0
for i in new_str:
if 'e' in i:
count+=1
print(i)
print(count)

Categories

Resources