Is there a pythonic way to insert space characters at random positions of an existing string? - string

is there a pythonic way to implement this:
Insert /spaces_1/ U+0020 SPACE
characters into /key_1/ at random
positions other than the start or end
of the string.
?
There /spaces_1/ is integer and /key_1/ is arbitrary existing string.
Thanks.

strings in python are immutable, so you can't change them in place. However:
import random
def insert_space(s):
r = random.randint(1, len(s)-1)
return s[:r] + ' ' + s[r:]
def insert_spaces(s):
for i in xrange(random.randrange(len(s))):
s = insert_space(s)
return s

Here's a list based solution:
import random
def insert_spaces(s):
s = list(s)
for i in xrange(len(s)-1):
while random.randrange(2):
s[i] = s[i] + ' '
return ''.join(s)

I'm going to arbitrarily decide you never want two spaces inserted adjacently - each insertion point used only once - and that "insert" excludes "append" and "prepend".
First, construct a list of insertion points...
insert_points = range (1, len (mystring))
Pick out a random selection from that list, and sort it...
import random
selected = random.sample (insert_points, 5)
selected.sort ()
Make a list of slices of your string...
selected.append (len (mystring)) # include the last slice
temp = 0 # start with first slice
result = []
for i in selected :
result.append (mystring [temp:i])
temp = i
Now, built the new string...
" ".join (result)

Just because no one used map yet:
import random
''.join(map(lambda x:x+' '*random.randint(0,1), s)).strip()

This method inserts a given number of spaces to a random position in a string and takes care that there are no double spaces after each other:
import random
def add_spaces(s, num_spaces):
assert(num_spaces <= len(s) - 1)
space_idx = []
space_idx.append(random.randint(0, len(s) - 2))
num_spaces -= 1
while (num_spaces > 0):
idx = random.randint(0, len(s) - 2)
if (not idx in space_idx):
space_idx.append(idx)
num_spaces -= 1
result_with_spaces = ''
for i in range(len(s)):
result_with_spaces += s[i]
if i in space_idx:
result_with_spaces += ' '
return result_with_spaces

If you want to add more than one space, then go
s[:r] + ' '*n + s[r:]

Here it comes...
def thePythonWay(s,n):
n = max(0,min(n,25))
where = random.sample(xrange(1,len(s)),n)
return ''.join("%2s" if i in where else "%s" for i in xrange(len(s))) % tuple(s)

We will randomly choose the locations where spaces will be added - after char 0, 1, ... n-2 of the string (n-1 is the last character, and we will not place a space after that); and then insert the spaces by replacing the characters in the specified locations with (the original character) + ' '. This is along the lines of Steve314's solution (i.e. keeping the assumption that you don't want consecutive spaces - which limits the total spaces you can have), but without using lists.
Thus:
import random
def insert_random_spaces(original, amount):
assert amount > 0 and amount < len(original)
insert_positions = sorted(random.sample(xrange(len(original) - 1), amount))
return ''.join(
x + (' ' if i in insert_positions else '')
for (i, x) in enumerate(original)
)

Related

Sorting strings without methods and other types

Hello I have to reorder a string, I am banned from using other types and str methods
So my problem is that I could not figure out how to end my code to get it work with any string
I tried to compare the results with sorted() to check and I am stuck at the first exchange
My code:
i = 0
s1 = "hello"
s2 = sorted(s1)
while (i<len(s1)):
j=i+1
while (j<=len(s1)-1):
if (s1[i] > s1[j]):
s1 = s1[0:i] + s1[j] + s1[i]
j+=1
i+=1
print(s1)
print(s2)
I tried to add + s1[len(s1):] at the end of the operation but
I only had found the result for a single string(that I was testing) adding thisI am really stuck, how can I make it work for all the strings with different lenghts??
Thanks
You're not reconstructing the string correctly when doing s1 = s1[0:i] + s1[j] + s1[i] as you're replacing one character for the other but you omit to actually interchange the two and to add the remains of the splitted string to the end of the new string.
Given what your code looks like, I would do it like this:
i = 0
s1 = "hello"
s2 = sorted(s1)
while i < len(s1):
j = i + 1
while j <= len(s1)-1:
if s1[i] > s1[j]:
s1 = s1[0:i] + s1[j] + s1[i+1:j] + s1[i] + s1[j+1:len(s1)]
j += 1
i += 1
print("".join(s2))
# > 'ehllo'
print(s1)
# > 'ehllo'
Please tell me if anything is unclear!
I am banned from using other types and str methods
Based upon your criteria, your request is impossible. Just accessing the elements of a string requires string methods.
The technique that you are using is very convoluted, hard to read and is difficult to debug. Try running your code in a debugger.
Now given that you are allowed to convert a string to a list (which requires string methods), redesign your code to use simple, easy to understand statements.
The following code first converts the string into a list. Then loops thru the list starting at the beginning and compares each following character to the end. If any character is less then the current character, swap. As you step thru the string, the character swaps will result in a sorted list. At the end convert the list back to a string using join().
msg = 'hello'
s = list(msg)
for i in range(len(s) - 1):
for j in range(i + 1, len(s)):
if s[i] <= s[j]:
continue
# swap characters
s[i], s[j] = s[j], s[i]
print(msg)
print(''.join(s))

How to shuffle two strings to a set of string in Python3

How can I shuffle two strings s||t (shuffle(s, t)) with the given requirement that the first char always stands in front of the second one in s and t as well no matter we shuffle. The result returns as a set of strings without duplicates.
I have the following test:
print(shuffle('ab', 'cd'))
Result:
['abcd', 'acbd', 'acdb', 'cabd', 'cadb', 'cdab']
Thanks a lot.
This method will shuffle two strings and return a list of shuffles between them where the order of the characters is the same as in the original strings. If there are duplicate characters there will be duplicate results as well.
def shuffle(s1, s2):
if len(s1) == 1:
return [s2[:i] + s1 + s2[i:] for i in range(len(s2) + 1)]
if len(s2) == 1:
return [s1[:i] + s2 + s1[i:] for i in range(len(s1) + 1)]
return [s1[0]+ s for s in shuffle(s1[1:], s2)] + [s2[0] + s for s in shuffle(s1, s2[1:])]
print shuffle("ab", "cd")
It works by getting the first character of each string and recursively shuffling the rest and adding this character to each element in the list. When there is one character remaining on each of the strings it returns a list where the character is added in each position of the other string. Hope it helps.
So you can apply a condition on final shuffled list to generate a new list from the shuffled one:
S=shuffle('ab','cd')
nl=[]
for w in S:
if(w.index('a')<w.index('b') and w.index('c')<w.index('d')):
nl.append(w)
So nl is your new list as per your requirement:)
If I understood the question correctly, this should work. Note, as you add letters to this, it becomes a long running problem. 4 letters have 6 possible combination for each entry in the list. 8 letters have 5,040 possible combinations for each entry in the list.
import random
import math
InputList = ['ab','cd']
PossibleUniqueCombinations = math.factorial(len("".join(InputList))-1)
print (PossibleUniqueCombinations)
TargetList = []
UniqueCombinationList = []
for lst in InputList:
UniqueCnt = 0
FirstChar = lst[0]
TheRest = list(lst[1:])
while UniqueCnt < PossibleUniqueCombinations:
if InputList.index(lst) == 0:
LeftList = []
else:
LeftList = InputList[0:InputList.index(lst)]
RightList = list(InputList[InputList.index(lst)+1:])
TargetList = LeftList + TheRest + RightList
TargetStr = ''.join(TargetList)
TargetStr = ''.join(random.sample(TargetStr, len(TargetStr)))
ShuffledStr = FirstChar + ''.join(TargetStr)
try:
FndIdx = UniqueCombinationList.index(ShuffledStr)
except ValueError:
UniqueCombinationList.append(ShuffledStr)
UniqueCnt += 1
for combo in UniqueCombinationList:
print(combo)

How can i remove the exact number of middle characters from a string?

I am trying to remove the number of middle characters in a string according to a given number. For example, if the string is mahir and I am told to remove one middle character, that would be h and the output would be mair, if the given number was 2, the output would have been mar.
I have worked out how the remove the middle characters but having troubles in removing it correctly. This is my code:
remover = int(input())
s = "mahir"
counter = len(s) - remover
while True:
h = len(s)//2
mod = (len(s) + 1) % 2
s = s[:h - mod] + s[h + 1:]
if len(s) == counter:
break
print(s)
If i enter remover more than one I end up getting an inifinte loop. How can i fix this and remove the correct number of middle characters?
You can slice the string like this:
s = 'mahir'
n = int(input())
i = (len(s) - n + 1) // 2
print(s[:i] + s[i + n:])

How would I reverse each word individually rather than the whole string as a whole

I'm trying to reverse the words in a string individually so the words are still in order however just reversed such as "hi my name is" with output "ih ym eman si" however the whole string gets flipped
r = 0
def readReverse(): #creates the function
start = default_timer() #initiates a timer
r = len(n.split()) #n is the users input
if len(n) == 0:
return n
else:
return n[0] + readReverse(n[::-1])
duration = default_timer() - start
print(str(r) + " with a runtime of " + str(duration))
print(readReverse(n))
First split the string into words, punctuation and whitespace with a regular expression similar to this. Then you can use a generator expression to reverse each word individually and finally join them together with str.join.
import re
text = "Hello, I'm a string!"
split_text = re.findall(r"[\w']+|[^\w]", text)
reversed_text = ''.join(word[::-1] for word in split_text)
print(reversed_text)
Output:
olleH, m'I a gnirts!
If you want to ignore the punctuation you can omit the regular expression and just split the string:
text = "Hello, I'm a string!"
reversed_text = ' '.join(word[::-1] for word in text.split())
However, the commas, exclamation marks, etc. will then be a part of the words.
,olleH m'I a !gnirts
Here's the recursive version:
def read_reverse(text):
idx = text.find(' ') # Find index of next space character.
if idx == -1: # No more spaces left.
return text[::-1]
else: # Split off the first word and reverse it and recurse.
return text[:idx][::-1] + ' ' + read_reverse(text[idx+1:])

How can I insert spaces at certain locations in a string (Python 2.7)?

I've found many related questions, and a couple that have at least helped me get this far. My goal is to have a function that receives a string and an arbitrary number of integers. I want the function to return that string with spaces inserted at the points given in the arguments. I will use this function with many different strings that will have varying numbers of inserts and insert locations.
This is an example of what I'd like to produce:
Input a string like 'ATGCATGCATGCATGC' and indexes (e.g. 4, 7). The output should be 'ATGCA TGC ATGCATGC'.
This is the function that has given me the closest results so far:
def breakRNA(seqRNA, *breakPoint):
n = 0
for i in seqRNA:
n += 1
for i in breakPoint:
if i == n:
seqRNA = seqRNA[n:] + ' ' + seqRNA[:n]
return seqRNA
The return string, however, is transposed out of order. Example:
>>> test = breakRNA('AAAAAAAAAAAAAAAAAAAAAAAAAAATTTTTGGGGGGGGCCCCCCCCCC', 5, 8, 14)
>>> test
>>> 'TTTTTGGGGGGGGCCCCCCCCCC AAAAA AAAAAAAA AAAAAAAAAAAAAA'
I am a day-1 beginner so any advice is appreciated. Thank you.
String are indexed like list in Python.
For example consider the following:
test_string = "azertyuiop"
print test_string[0] #will return 'a'
print test_string[0:2] #will return 'az'
So getting back to your problem:
def insert_space(string, integer):
return string[0:integer] + ' ' + string[integer:]
Hope this is what you are looking for
def breakRNA(seqRNA, *breakPoint):
seqRNAList = []
noOfBreakPoints = len(breakPoint)
for breakPt in range(noOfBreakPoints):
for index in breakPoint:
seqRNAList.append(seqRNA[:index])
seqRNA = seqRNA[index:]
break
return seqRNAList
test = breakRNA('AAAAAAAAAAAAAAAAAAAAAAAAAAATTTTTGGGGGGGGCCCCCCCCCC', 5, 8, 14)
print test
This will return you alist then you can create a string out of it using join function.
simbol = input('Enter a character:\n')
triangle_n = int(input('Enter triangle height:\n'))
print('')
for i in range (triangle_n ):
for j in range(i+1):
print(simbol [0],end=' ')
print()
string_name = string_name[starting index:ending index] + ' ' + string_name[starting index:ending index]
example:
product_rating = '4.56888 rating 256156 reviews'
product_rating = product_rating[0:3] + ' ' + product_rating[3:]
output
'4.5 6888 rating 256156 reviews'
If ending index is not mentioned its default value will be till the end of string.
Note indexing will start from 0 and 0:3 means it will take 0 to 2.

Resources