Removing And Re-Inserting Spaces

Viewed 168

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?

6 Answers

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)

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)

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.

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
Related