excess trailing concatenation of a string - python

I'm trying to write a function that will take a list and convert it to a string separated by - or a ,.
I have to use a loop for this so I came up with the following.
My problem is that I can't get rid of trailing separator. any ideas?
Output is : String is r-i-n-g-i-n-g-
should be : String is r-i-n-g-i-n-g
#A list created for the purpose of converting it to a string)
c_list = ['r', 'i', 'n', 'g', 'i', 'n', 'g']
# Function to_string()
def to_string(my_list, sep=', '):
counter = 0
mystring = ''
for n in my_list:
n = str(n)
mystring = mystring + n
mystring = mystring + sep
return mystring
print('String is', to_string(c_list, '-'))

You can use the str.join method instead:
print('String is', '-'.join(c_list))
If you need to use a loop, however, you can make adding the separator the first thing to do in your loop instead, but make it conditional on that there is already content in mystring, so that it does not add the separator in the first iteration:
c_list = ['r', 'i', 'n', 'g', 'i', 'n', 'g']
# Function to_string()
def to_string(my_list, sep=', '):
counter = 0
mystring = ''
for n in my_list:
if mystring:
mystring = mystring + sep
n = str(n)
mystring = mystring + n
return mystring
print('String is', to_string(c_list, '-'))

In return statement you can use string slicing to remove trailing delimiter.
return mystring[:-1]
This will remove the last character in the string.

Related

Replacing a character from a certain index [duplicate]

This question already has answers here:
Changing one character in a string
(15 answers)
Closed 2 years ago.
How can I replace a character in a string from a certain index? For example, I want to get the middle character from a string, like abc, and if the character is not equal to the character the user specifies, then I want to replace it.
Something like this maybe?
middle = ? # (I don't know how to get the middle of a string)
if str[middle] != char:
str[middle].replace('')
As strings are immutable in Python, just create a new string which includes the value at the desired index.
Assuming you have a string s, perhaps s = "mystring"
You can quickly (and obviously) replace a portion at a desired index by placing it between "slices" of the original.
s = s[:index] + newstring + s[index + 1:]
You can find the middle by dividing your string length by 2 len(s)/2
If you're getting mystery inputs, you should take care to handle indices outside the expected range
def replacer(s, newstring, index, nofail=False):
# raise an error if index is outside of the string
if not nofail and index not in range(len(s)):
raise ValueError("index outside given string")
# if not erroring, but the index is still not in the correct range..
if index < 0: # add it to the beginning
return newstring + s
if index > len(s): # add it to the end
return s + newstring
# insert the new string between "slices" of the original
return s[:index] + newstring + s[index + 1:]
This will work as
replacer("mystring", "12", 4)
'myst12ing'
You can't replace a letter in a string. Convert the string to a list, replace the letter, and convert it back to a string.
>>> s = list("Hello world")
>>> s
['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']
>>> s[int(len(s) / 2)] = '-'
>>> s
['H', 'e', 'l', 'l', 'o', '-', 'W', 'o', 'r', 'l', 'd']
>>> "".join(s)
'Hello-World'
Strings in Python are immutable meaning you cannot replace parts of them.
You can however create a new string that is modified. Mind that this is not semantically equivalent since other references to the old string will not be updated.
You could for instance write a function:
def replace_str_index(text,index=0,replacement=''):
return '%s%s%s'%(text[:index],replacement,text[index+1:])
And then for instance call it with:
new_string = replace_str_index(old_string,middle)
If you do not feed a replacement, the new string will not contain the character you want to remove, you can feed it a string of arbitrary length.
For instance:
replace_str_index('hello?bye',5)
will return 'hellobye'; and:
replace_str_index('hello?bye',5,'good')
will return 'hellogoodbye'.
# Use slicing to extract those parts of the original string to be kept
s = s[:position] + replacement + s[position+length_of_replaced:]
# Example: replace 'sat' with 'slept'
text = "The cat sat on the mat"
text = text[:8] + "slept" + text[11:]
I/P : The cat sat on the mat
O/P : The cat slept on the mat
You can also Use below method if you have to replace string between specific index
def Replace_Substring_Between_Index(singleLine,stringToReplace='',startPos,endPos):
singleLine = singleLine[:startPos]+stringToReplace+singleLine[endPos:]
return singleLine

returning a list of strings separated by a delimiter

Im having some problems trying to solve this question. Its from a practice exam and I just can't seem to get it right. Im supposed to write a python function that takes in a string and a delimiter, and return a list back with the string stripped of the delimiter. We are not allowed to use the split function or "any such function". The example we received in the question was this
StringToken("this is so fun! I love it!", "!")
Outputs
["this is so fun", "I love it"]
This is the code I made up, its super simple.
def tokenizer(string, tmp):
newStr = []
for i in range(len(string)):
if string[i] != tmp:
newStr.append(string[i])
return newStr
and the output is this
['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 's', 'o', ' ', 'f', 'u', 'n', ' ', 'I', ' ', 'l', 'o', 'v', 'e', ' ', 'i', 't']
How can I rejoin each word?
If you join all the elements in the list you will get a single string which may not be what you are looking for.
Create a string before append it to the list like;
>>> def StringToken(string, tmp):
newStrlist = []
newStr = ''
for i in range(len(string)):
if string[i] != tmp:
newStr += string[i]
elif newStr != '':
newStrlist.append(newStr)
newStr = ''
return newStrlist
... ... ... ... ... ... ... ... ... ...
>>> StringToken("this is so fun! I love it!", "!")
['this is so fun', ' I love it']
Instead of looping over the all the letters in the string, you can use find to get the index of the next occurrence of the delimiter and then build your list accordingly:
def tokenizer(string, delim):
new_list = []
while True:
index = string.find(delim) # use find to next occurrence of delimiter
if index > -1:
new_list.append(string[:index])
string = string[index + len(delim):]
else:
new_list.append(string)
break # break because there is no delimiter present anymore
# remove whitespaces and trim the existing strings
return [item.strip() for item in new_list if item.strip()]
Usage:
>>> tokenizer("this is so fun! I love it!", "!")
["this is so fun", "I love it"]
See comments in the code for a description.
def StringToken(string, tmp):
newStr = "" # A string to build upon
lst = [] # The list to return
for c in string: # Iterate over the characters
if tmp == c: # Check for the character to strip
if newStr != "": # Prevent empty strings in output
lst.append(newStr.strip()) # add to the output list
newStr = "" # restart the string
continue # move to the next character
newStr += c # Build the string
return lst # Return the list
Output
StringToken("this is so fun! I love it!", "!")
# ['this is so fun', 'I love it']
Here's an alternative that's a little shorter than the current answers:
def StringToken(string, tmp):
newStr = []
start = 0
for ind, char in enumerate(string):
if char == tmp:
newStr.append(string[start:ind])
start = ind + 1
return newStr
Output
>>> StringToken("this is so fun! I love it!", "!")
['this is so fun', ' I love it']
Edit:
If you would like to remove leading or trailing spaces like in your example, that can be done using strip():
def StringToken(string, tmp):
newStr = []
start = 0
for ind, char in enumerate(string):
if char == tmp:
newStr.append(string[start:ind].strip())
start = ind + 1
return newStr
Output
>>> StringToken("this is so fun! I love it!", "!")
['this is so fun', 'I love it']
simply use join operator this will join entire list with a given delimiter.
Here in this you can use empty delimiter ''.
try:
a=['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 's', 'o', ' ', 'f', 'u', 'n', ' ', 'I', ' ', 'l', 'o', 'v', 'e', ' ', 'i', 't']
''.join(a)
output will be
'This is so fun I love it'

Returning the value of an index in a python list based on other values

I have put the letters a-z in a list. How would I find the value of an item in the list depending on what the user typed?
For example if they type the letter a it would return c, f would return h and x would return z.
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
newletters = []
offset = 2
userInput = input('type a string')
newvalue = chr(ord(userInput)+offset)
split = list(newvalue)
print split
the above works for a character but not for a string..help?!
You can try this:
>>> offset = 2
>>> aString = raw_input("digit a letter: ")
>>> aString
'a'
>>> chr(ord(aString)+offset)
'c'
documentation:
https://docs.python.org/2/library/functions.html#chr
https://docs.python.org/2/library/functions.html#ord
If you want to iterate over an entire string, a simple way is using a for loop. I assume the input string is always lowercase.
EDIT2: I improved the solution to handle the case when a letter is 'y' or 'z' and without "rotation" should begin a not alphabetic character, eg:
# with only offset addiction this return a non-alphabetic character
>>> chr(ord('z')+2)
'|'
# the 'z' rotation return the letter 'b'
>>> letter = "z"
>>> ord_letter = ord(letter)+offset
>>> ord_letter_rotated = ((ord_letter - 97) % 26) + 97
>>> chr(ord_letter_rotated)
'b'
The code solution:
offset = 2
aString = raw_input("digit the string to convert: ")
#aString = "abz"
newString = ""
for letter in aString:
ord_letter = ord(letter)+offset
ord_letter_rotated = ((ord_letter - 97) % 26) + 97
newString += chr(ord_letter_rotated)
print newString
The output of this code for the entire lowercase alphabet:
cdefghijklmnopqrstuvwxyzab
Note: you can obtain the lowercase alphabet for free also this way:
>>> import string
>>> string.lowercase
'abcdefghijklmnopqrstuvwxyz'
See the wikipedia page to learn something about ROT13:
https://en.wikipedia.org/wiki/ROT13
What should happen for z? Should it become b?
You can use Python's maketrans and translate functions to do this as follows:
import string
def rotate(text, by):
s_from = string.ascii_lowercase
s_to = string.ascii_lowercase[by:] + string.ascii_lowercase[:by]
cypher_table = string.maketrans(s_from, s_to)
return text.translate(cypher_table)
user_input = raw_input('type a string: ').lower()
print rotate(user_input, 2)
This works on the whole string as follows:
type a string: abcxyz
cdezab
How does it work?
If you print s_from and s_to they look as follows:
abcdefghijklmnopqrstuvwxyz
cdefghijklmnopqrstuvwxyzab
maketrans creates a mapping table to map characters in s_from to s_to. translate then applies this mapping to your string.

how to use a for loop to replacing index useing python

Define a function named encrypt which takes as input a string (which is the name of a text file in the current directory). The function should then print the encrypted content of this file.
Here text encryption is done by replacing every occurence of a vowel with its next in the list 'aeiou'. So 'a' is replaced by 'e', 'e' is replaced by 'i', so on and 'u' is replaced by 'a'. Also each consonant is replaced with its next in the list 'bcdfghjklmnpqrstvwxyz' so 'b' is replaced by 'c', 'c' by 'd' so on and lastly 'z' is replaced by 'b'. The same replacement logic holds for upper case letters. Note that non-alphabetic characters should appear in their original form without modification.
def encrypt (eo):
vowel = 'aeiou'
con = 'bcdfghjklmnpqrstvwxyz'
for eo in vowel (t[i+1]):
res=
return res
This piece of code could be useful. Pay attention to the vowel and con content. I appended one letter in each variable vowel and com to avoid the modulo operation. Assume the eo is the input string.
def encrypt (eo):
vowel = 'aeioua'
con = 'bcdfghjklmnpqrstvwxyzb'
encrytTable = vowel + con
res = ""
for letter in eo:
res += encrytTable[encrytTable.find(letter)+1]
return res
If eo is the input filename, you need some file read operation like:
>>> fh = open(eo)
>>> fh.read()
>>> fh.>>> fh.close()
And a more effient way to do it, is pre-compute a encryptTable array and use the table to replace the origianl input in a linear manner. In following code, I assume your input only include lower-case letters. Abd if the shift distance is not 1, you need to modify the code. Pre-compute:
>>> vowel = 'aeioua'
>>> con = 'bcdfghjklmnpqrstvwxyzb'
>>> encryptTable = []
>>> for i in xrange(97,123):
temp = chr(i)
if temp in vowel:
encryptTable.append(vowel[vowel.find(temp)+1])
else:
encryptTable.append(con[con.find(temp)+1])
>>> encryptTable
['e', 'c', 'd', 'f', 'i', 'g', 'h', 'j', 'o', 'k', 'l', 'm', 'n', 'p', 'u', 'q', 'r', 's', 't', 'v', 'a', 'w', 'x', 'y', 'z', 'b']
And then replace the content:
>>> plain = "helloworld"
>>> encrypted = "".join([encryptTable[ord(i)-ord('a')] for i in plain])
>>> encrypted
'jimmuxusmf'
def encrypt(s):
vowels = 'aeiou'
vowelReps = dict(zip(vowels, vowels[1:]+vowels[0]))
cons = 'bcdfghjklmnpqrstvwxyz'
consReps = dict(zip(cons, cons[1:]+cons[0]))
answer = []
for char in s:
if char.lower() in vowelReps:
answer.append(vowelReps[char.lower()]
else:
answer.append(consReps[char.lower()]
if char.isupper():
answer[-1] = answer[-1].upper()
return ''.join(answer)
You have multiple problems here:
for eo in ... would replace the eo argument; except
t isn't defined, so will give a NameError;
res= is a SyntaxError; and
Even if all of the above was fixed, return res will happen on the first character, as it is indented too far.
Instead, you could do the following:
def encrypt(eo):
vowels = "aeiou"
for index, vowel in enumerate(vowels): # iterate through the five vowels
new_v = vowels[(index + 1) % len(vowels)] # determine replacement
eo = eo.replace(vowel, new_v) # do replacement
You can then do the same thing for the consonants, then return eo (which should be indented to the same level as vowels = ...!).
Note:
the use of % to keep the index into vowels within the appropriate range; and
the use of enumerate to get both the character vowel from the string vowels and its index within that string.
Alternatively, and more efficiently:
build a dictionary mapping character in to character out;
build a list of replacement characters using the input eo and the dict; and
str.join the output characters together and return it.

How to sort the letters in a string alphabetically in Python

Is there an easy way to sort the letters in a string alphabetically in Python?
So for:
a = 'ZENOVW'
I would like to return:
'ENOVWZ'
You can do:
>>> a = 'ZENOVW'
>>> ''.join(sorted(a))
'ENOVWZ'
>>> a = 'ZENOVW'
>>> b = sorted(a)
>>> print b
['E', 'N', 'O', 'V', 'W', 'Z']
sorted returns a list, so you can make it a string again using join:
>>> c = ''.join(b)
which joins the items of b together with an empty string '' in between each item.
>>> print c
'ENOVWZ'
Sorted() solution can give you some unexpected results with other strings.
List of other solutions:
Sort letters and make them distinct:
>>> s = "Bubble Bobble"
>>> ''.join(sorted(set(s.lower())))
' belou'
Sort letters and make them distinct while keeping caps:
>>> s = "Bubble Bobble"
>>> ''.join(sorted(set(s)))
' Bbelou'
Sort letters and keep duplicates:
>>> s = "Bubble Bobble"
>>> ''.join(sorted(s))
' BBbbbbeellou'
If you want to get rid of the space in the result, add strip() function in any of those mentioned cases:
>>> s = "Bubble Bobble"
>>> ''.join(sorted(set(s.lower()))).strip()
'belou'
Python functionsorted returns ASCII based result for string.
INCORRECT: In the example below, e and d is behind H and W due it's to ASCII value.
>>>a = "Hello World!"
>>>"".join(sorted(a))
' !!HWdellloor'
CORRECT: In order to write the sorted string without changing the case of letter. Use the code:
>>> a = "Hello World!"
>>> "".join(sorted(a,key=lambda x:x.lower()))
' !deHllloorW'
OR (Ref: https://docs.python.org/3/library/functions.html#sorted)
>>> a = "Hello World!"
>>> "".join(sorted(a,key=str.lower))
' !deHllloorW'
If you want to remove all punctuation and numbers.
Use the code:
>>> a = "Hello World!"
>>> "".join(filter(lambda x:x.isalpha(), sorted(a,key=lambda x:x.lower())))
'deHllloorW'
You can use reduce
>>> a = 'ZENOVW'
>>> reduce(lambda x,y: x+y, sorted(a))
'ENOVWZ'
the code can be used to sort string in alphabetical order without using any inbuilt function of python
k = input("Enter any string again ")
li = []
x = len(k)
for i in range (0,x):
li.append(k[i])
print("List is : ",li)
for i in range(0,x):
for j in range(0,x):
if li[i]<li[j]:
temp = li[i]
li[i]=li[j]
li[j]=temp
j=""
for i in range(0,x):
j = j+li[i]
print("After sorting String is : ",j)
Really liked the answer with the reduce() function. Here's another way to sort the string using accumulate().
from itertools import accumulate
s = 'mississippi'
print(tuple(accumulate(sorted(s)))[-1])
sorted(s) -> ['i', 'i', 'i', 'i', 'm', 'p', 'p', 's', 's', 's', 's']
tuple(accumulate(sorted(s)) -> ('i', 'ii', 'iii', 'iiii', 'iiiim', 'iiiimp', 'iiiimpp', 'iiiimpps', 'iiiimppss', 'iiiimppsss', 'iiiimppssss')
We are selecting the last index (-1) of the tuple

Categories

Resources