Strings, Loops
We can do this by “tokenizing” our string — converting it into a list of “tokens”, with each token being either a word or a series of spaces. Once we’ve done that, we can just reverse the list of tokens:
def rev(s):
"""Reverse word-order in string, preserving spaces."""
# START SOLUTION
# A token is either a word or a series of spaces --- so,
# for example, we would turn " hello kitty "
# into the tokens = [" ", "hello", " ", "kitty", " "].
# The current token we're building up.
current_token = ''
# List of tokens found so far
tokens = []
# True when we're collecting spaces
# False when we're collecting non-spaces
in_space = None
for letter in s:
if letter == " ":
if not in_space:
# Switch from space -> letter: add the current
# (letter-y) token and restart our current_token
tokens.append(current_token)
current_token = ''
in_space = True
else:
if in_space:
# Switch from letter -> space: add the current
# (space-y) token and restart our current_token
tokens.append(current_token)
current_token = ''
in_space = False
# Add this letter to our current_token
current_token += letter
# Finished, add the ending token to our list
tokens.append(current_token)
# Reverse tokens as string ['hi', ' ', 'world'] -> "world hi"
return ''.join(reversed(tokens))
Alternatively, if we split the string on spaces, we’ll get everything which appears in between consecutive spaces — even if that’s an empty string! Then we can just reverse the list and put the spaces back in:
def rev2(s):
"""Reverse word-order in string, preserving spaces."""
# Splitting on space will give us both the words and empty strings - there
# will be an empty string each time two spaces are next to each other
#
# Then we just reverse the order and put the spaces back in
return " ".join(reversed(s.split(" ")))
While this problem is interesting and worthwhile to solve directly, as above, it could also be solved using regular expressions, a mini-language for text matching and replacement supported by Python’s re library:
import re
def rev(s):
"""Turn " hello kitty " -> " kitty hello "."""
tokens = re.findall(" +|[^ ]+", s)
return "".join(reversed(tokens))
(For people with some experience with regular expressions, you can read that as “Match as many spaces as possible or as many non-spaces as possible)
Regular expressions often provide terse but useful solutions for text matching.