I am looking for a way to add spaces between words in a string until len(string) < n is reached.
I've tried this:
string = "you are great"
n = 20
res = []
for i in string:
if ord(i) == 32 and len(string) < num:
res = [string + i]
And I want it to add spaces between "you" and "are", and "are" and "great.
So it gives me something like this:
res = ["you are great"]
But instead I get this
"you are great "
No need of loops:
string = "you are great"
n = 20
a = n - len(string.replace(' ', '')) # amount of spaces to add
b = string.split() # list of words (without spaces)
if a & 1:
b[0] += ' ' # if 'a' is odd, add an extra space to first word
d = (' ' * (a // 2)).join(b) # concatenate all words with 'a' spaces between them
print(d)
The output is:
"you are great"
You code is doing what it is suppose to do but as you can see in the second output it adds a space to your string. The code below is the issue.
Res = [string + i]
I have several strings like below. How can I get the dot, except the decimal dot?
Please note: I need the digit after the decimal. I don't want to lose the decimal dot and the digit after that.
For example:
"8.2"
"88.2"
"888.2"
"8.888.2"
"8.888.888.2"
The output will be like this:
"8.2"
"88.2"
"888.2"
"8888.2"
"8888888.2"
Use str.rpartition. It will work correctly even when there isn't a . in the input, as evident below.
def fix_number(n):
a, sep, b = n.rpartition(".")
return a.replace(".", "") + sep + b
for case in ["8.2", "88.2", "888.2", "8.888.2", "8.888.888.2", "8"]:
print(case, fix_number(case))
8.2 8.2
88.2 88.2
888.2 888.2
8.888.2 8888.2
8.888.888.2 8888888.2
8 8
One way would be to split on the dots, then join together, treating the last one specially:
s = '8.888.888.2'
*whole, decimal = s.split('.')
res = ''.join(whole) + '.' + decimal # gives: 8888888.2
You can use a similar method if you want to replace the thousands and/or decimal separators with another character:
s = '8.888.888.2'
*whole, decimal = s.split('.')
res = "'".join(whole) + ',' + decimal # gives: 8'888'888,2
Another idea is to call str.replace() with the optional third argument count, which will replace only the first count occurrences of the character.
If we set count to be equal to the number of "." minus one we get the desired result:
words = ["8.2", "88.2", "888.2", "8.888.2", "8.888.888.2"]
new_words = []
for word in words:
new_word = word.replace('.', '', word.count('.')-1)
new_words.append(new_word)
print(new_words)
Output
['8.2', '88.2', '888.2', '8888.2', '8888888.2']
I have broken down the code into simpler lines for better understanding and readability.
Try this:
words = ["8", "8.2", "88.2", "888.2", "8.888.2", "8.888.888.2"]
changed_word = []
for word in words:
split_word = word.split(".")
if len(split_word) > 2:
before_decimal = "".join(split_word[0:len(split_word)-1])
after_decimal = split_word[-1]
final_word = before_decimal + "." + after_decimal
else:
final_word = word
changed_word.append(final_word)
print(changed_word)
The output is:
['8', '8.2', '88.2', '888.2', '8888.2', '8888888.2']
The next step: try to optimise this code in fewer lines.
You can use re here.
\.(?=.*\.)
Just replace with empty string.
See demo.
https://regex101.com/r/T9iX3B/1
import re
regex = r"\.(?=.*\.)"
test_str = ("\"8.2\"\n\n"
"\"88.2\"\n\n"
"\"888.2\"\n\n"
"\"8.888.2\"\n\n"
"\"8.888.888.2\" \n"
"8\n\n"
"the out put will be like this:\n\n"
" ")
subst = ""
# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)
if result:
print (result)
x = "8.888.888.22"
y = x.split(".")
z = "".join(y[:-1]) + "." + y[-1]
print(z)
# '8888888.22'
a = ["8", "8.2", "88.2", "888.2", "8.888.2", "8.888.888.2"]
for x in a:
if '.' not in x:
print(x)
continue
ridx = x.rindex('.')
print(x[:ridx].replace('.', '') + x[ridx:])
You need to find the last occurrence of the dot(.). And then before that index, replace all the dots with an empty character, and add the remaining part of the string:
s = "8.888.888.2"
last = -1
for index, item in enumerate(s):
if item == ".":
last = max(index, last)
if last != -1:
s = s[:last].replace(".", "") + s[last:]
print(s)
There are two ways I can imagine to solve your problem.
The first one is by parsing the string to another variable
example = 8888888.2
example = str(example) # In case that your input was in another type format
example_1 = example[-1:]
The output in this case would be "2".
For the second way, you can simple split the string into a list, and then you get only what you want:
example = 8888888.2
example = str(example)
example_2 = example.split('.') # Inside the parenthesis you can put the element you want to split the string, like a space, a comma, a dot
example_output = example[1]
In this case, the output was still the same "2" and in both cases you maintain your base variable just in case that you want the original input.
A simpler function:
def remove_dot(word):
dot_cnt = word.count('.')
if dot_cnt <= 1:
return word
else:
word = word.replace(".", "", dot_cnt - 1)
return word
print(remove_dot("8.888.888.2"))
output : = 8888888.2
Yet another solution, without special functions
(inspired by the answer from #AKX).
def fix_number(n):
return int( n.replace(".","") ) / ( 10 ** ('.' in n) )
for case in ["8.2", "88.2", "888.2", "8.888.2", "8.888.888.2", "8", ""8.888.888"]:
print(case, fix_number(case))
The idea is that '.' in n returns 0 (False) if there are no dots, in which case we divide by 10^0 = 1. It returns 1 (True) if there are one or more dots, in which case we divide by 10.
8.2 8.2
88.2 88.2
888.2 888.2
8.888.2 8888.2
8.888.888.2 8888888.2
8 8.0
8.888.888 888888.8 <- not correct
As you can see, it returns a float even when there are no decimals. Not that the OP asked, but I think that's a nice feature :). However, it fails on the last test-case (which is not among the examples from the OP).
For this case we can replace the function with
def fix_number(n):
return int( n.replace(".","") ) / ( 10 ** ('.' == n[-2]) )
but this fails on 8.
Fixing that leads us to
def fix_number(n):
return int( n.replace(".","") ) / ( 10 ** (n.rfind('.') == max(0,len(n)-2)) )
which outputs
8.2 8.2
88.2 88.2
888.2 888.2
8.888.2 8888.2
8.888.888.2 8888888.2
8 8.0
8.888.888 8888888.0
But at this point is gets a bit ridiculous :). Also the answer by #AKX is about 3.5 times faster.
I need to move a whitespace in a string one position to the right.
This is my code:
for i in range(0,len(resultaat)):
if resultaat[i] == " ":
string = resultaat[:i] + resultaat[i+1] + " " + resultaat[i+2:]
E.g.:
If resultaat =
"TH EZE NO FPYTHON."
Than my output needs to be:
'THE ZEN OF PYTHON.'
, but the output that I get is:
"TH EZE NO F PYTHON."
I think this happened because the loop undid the action where it moved the previous space.
I don't know how to fix this problem.
Can someone help me with this?
Thanks!
Each time through the loop you're getting slices of the original resultaat string, without the changes you've made for previous iterations.
You should copy resultaat to string first, then use that as the source of each slice so you accumulate all the changes.
string = resultaat
for i in range(0,len(resultaat)):
if resultaat[i] == " ":
string = string[:i] + string[i+1] + " " + string[i+2:]
You could do something like this:
# first get the indexes that the character you want to merge
indexes = [i for i, c in enumerate(resultaat) if c == ' ']
for i in indexes: # go through those indexes and swap the characters as you have done
resultaat = resultaat[:i] + resultaat[i+1] + " " + resultaat[i+2:] # updating resultaat each time you want to swap characters
Assuming the stated input value actually has one more space than is actually needed then:
TXT = "TH EZE NO FPYTHON."
def process(s):
t = list(s)
for i, c in enumerate(t[:-1]):
if c == ' ':
t[i+1], t[i] = ' ', t[i+1]
return ''.join(t)
print(process(TXT))
Output:
THE ZEN OF PYTHON.
I have two strings, say 'a' and 'b'. I want to compare 'a' against 'b' and extract only the unique part of 'a'. I could simply check if 'b' is in a and extract. But the issue here is, either string 'a' or 'b' has randomly ignored whitespaces, thus making it slightly difficult.
Here is what I have done so far
a = "catsand dogs some other strings"
b = "cats and dogs"
a_no_space = a.replace(" ", "")
b_no_space = b.replace(" ", "")
if(b_no_space in a_no_space and len(a_no_space) > len(b_no_space)):
unique = a[b_no_space.index(b_no_space)+len(b_no_space):]
With this solution, I get the following result
s some other strings
I don't want that 's' in the beginning. How can I fix this in python?
Does using regex help here? If so how?
You can convert your search string to a regular expression where spaces are replaced by '\s*' which will accept any number of intermediate spaces between words (including no spaces):
a = "catsand dogs some other strings"
b = "cats and dogs"
import re
pattern = r"\s*".join(map(re.escape,re.split("\s+",b))) # r'cats\s*and\s*dogs'
r = re.sub(pattern,"",a) # ' some other strings'
Here is a solution that progressively slices the larger string according to the letters of the substring:
idx = 0
if len(a) > len(b):
for letter in b:
if letter in a and letter != " ":
a= a[a.index(letter) + 1:]
print(a)
else:
for letter in a:
if letter in b and letter != " ":
b= b[b.index(letter) + 1:]
print(b)
What is the most efficient way to remove spaces from a text, and then after the neccessary function has been performed, re-insert the previously removed spacing?
Take this example below, here is a program for encoding a simple railfence cipher:
from string import ascii_lowercase
string = "Hello World Today"
string = string.replace(" ", "").lower()
print(string[::2] + string[1::2])
This outputs the following:
hlooltdyelwrdoa
This is because it must remove the spacing prior to encoding the text. However, if I now want to re-insert the spacing to make it:
hlool tdyel wrdoa
What is the most efficient way of doing this?
As mentioned by one of the other commenters, you need to record where the spaces came from then add them back in
from string import ascii_lowercase
string = "Hello World Today"
# Get list of spaces
spaces = [i for i,x in enumerate(string) if x == ' ']
string = string.replace(" ", "").lower()
# Set string with ciphered text
ciphered = (string[::2] + string[1::2])
# Reinsert spaces
for space in spaces:
ciphered = ciphered[:space] + ' ' + ciphered[space:]
print(ciphered)
You could use str.split to help you out. When you split on spaces, the lengths of the remaining segments will tell you where to split the processed string:
broken = string.split(' ')
sizes = list(map(len, broken))
You'll need the cumulative sum of the sizes:
from itertools import accumulate, chain
cs = accumulate(sizes)
Now you can reinstate the spaces:
processed = ''.join(broken).lower()
processed = processed[::2] + processed[1::2]
chunks = [processed[index:size] for index, size in zip(chain([0], cs), sizes)]
result = ' '.join(chunks)
This solution is not especially straightforward or efficient, but it does avoid explicit loops.
Using list and join operation,
random_string = "Hello World Today"
space_position = [pos for pos, char in enumerate(random_string) if char == ' ']
random_string = random_string.replace(" ", "").lower()
random_string = list(random_string[::2] + random_string[1::2])
for index in space_position:
random_string.insert(index, ' ')
random_string = ''.join(random_string)
print(random_string)
I think this might Help
string = "Hello World Today"
nonSpaceyString = string.replace(" ", "").lower()
randomString = nonSpaceyString[::2] + nonSpaceyString[1::2]
spaceSet = [i for i, x in enumerate(string) if x == " "]
for index in spaceSet:
randomString = randomString[:index] + " " + randomString[index:]
print(randomString)
string = "Hello World Today"
# getting index of ' '
index = [i for i in range(len(string)) if string[i]==' ']
# storing the non ' ' characters
data = [i for i in string.lower() if i!=' ']
# applying cipher code as mention in OP STATEMENT
result = data[::2]+data[1::2]
# inserting back the spaces in there position as they had in original string
for i in index:
result.insert(i, ' ')
# creating a string solution
solution = ''.join(result)
print(solution)
# output hlool tdyel wrdoa
You can make a new string with this small yet simple (kind of) code:
Note this doesn't use any libraries, which might make this slower, but less confusing.
def weird_string(string): # get input value
spaceless = ''.join([c for c in string if c != ' ']) # get spaceless version
skipped = spaceless[::2] + spaceless[1::2] # get new unique 'code'
result = list(skipped) # get list of one letter strings
for i in range(len(string)): # loop over strings
if string[i] == ' ': # if a space 'was' here
result.insert(i, ' ') # add the space back
# end for
s = ''.join(result) # join the results back
return s # return the result