How would I reverse each word individually rather than the whole string as a whole - python-3.x

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:])

Related

Create a List with spaces without and not using .split()

I have to write an application that asks the user to enter a list of numbers separated by a space and then prints the sum of the numbers. The user can enter any number of numbers. I am not allowed to use the split function in python. I was wondering how I can do it that. Any help would be appreciated it as I'm kind of stuck on where to start.
Possible solution is to use regular expressions:
# import regular expression library
import re
# let user enter numbers and store user data into 'data' variable
data = input("Enter numbers separated by space: ")
"""
regular expression pattern '\d+' means the following:
'\d' - any number character,
'+' - one or more occurence of the character
're.findall' will find all occurrences of regular expression pattern
and store to list like '['1', '258', '475', '2', '6']'
please note that list items stored as str type
"""
numbers = re.findall(r'\d+', data)
"""
list comprehension '[int(_) for _ in numbers]' converts
list items to int type
'sum()' - summarizes list items
"""
summary = sum([int(_) for _ in numbers])
print(f'Sum: {summary}')
Another solution is following:
string = input("Enter numbers separated by space: ")
splits = []
pos = -1
last_pos = -1
while ' ' in string[pos + 1:]:
pos = string.index(' ', pos + 1)
splits.append(string[last_pos + 1:pos])
last_pos = pos
splits.append(string[last_pos + 1:])
summary = sum([int(_) for _ in filter(None, splits)])
print(f'Sum: {summary}')
From my point of view, the first option is more concise and better protected from user errors.

Skipping spaces in Groovy

I'm trying to write a conditional statement where I can skip a specific space then start reading all the characters after it.
I was thinking to use substring but that wouldn't help because substring will only work if I know the exact number of characters I want to skip but in this case, I want to skip a specific space to read characters afterward.
For example:
String text = "ABC DEF W YZ" //number of characters before the spaces are unknown
String test = "A"
if ( test == "A") {
return text (/*escape the first two space and return anything after that*/)
}
You can split your string on " " with tokenize, remove the first N elements from the returned array (where N is the number of spaces you want to ignore) and join what's left with " ".
Supposing your N is 2:
String text = "ABC DEF W YZ" //number of characters before the spaces are unknown
String test = "A"
if ( test == "A") {
return text.tokenize(" ").drop(2).join(" ")
}

Python 2.7 - remove special characters from a string and camelCasing it

Input:
to-camel-case
to_camel_case
Desired output:
toCamelCase
My code:
def to_camel_case(text):
lst =['_', '-']
if text is None:
return ''
else:
for char in text:
if text in lst:
text = text.replace(char, '').title()
return text
Issues:
1) The input could be an empty string - the above code does not return '' but None;
2) I am not sure that the title()method could help me obtaining the desired output(only the first letter of each word before the '-' or the '_' in caps except for the first.
I prefer not to use regex if possible.
A better way to do this would be using a list comprehension. The problem with a for loop is that when you remove characters from text, the loop changes (since you're supposed to iterate over every item originally in the loop). It's also hard to capitalize the next letter after replacing a _ or - because you don't have any context about what came before or after.
def to_camel_case(text):
# Split also removes the characters
# Start by converting - to _, then splitting on _
l = text.replace('-','_').split('_')
# No text left after splitting
if not len(l):
return ""
# Break the list into two parts
first = l[0]
rest = l[1:]
return first + ''.join(word.capitalize() for word in rest)
And our result:
print to_camel_case("hello-world")
Gives helloWorld
This method is quite flexible, and can even handle cases like "hello_world-how_are--you--", which could be difficult using regex if you're new to it.

Python Join String to Produce Combinations For All Words in String

If my string is this: 'this is a string', how can I produce all possible combinations by joining each word with its neighboring word?
What this output would look like:
this is a string
thisis a string
thisisa string
thisisastring
thisis astring
this isa string
this isastring
this is astring
What I have tried:
s = 'this is a string'.split()
for i, l in enumerate(s):
''.join(s[0:i])+' '.join(s[i:])
This produces:
'this is a string'
'thisis a string'
'thisisa string'
'thisisastring'
I realize I need to change the s[0:i] part because it's statically anchored at 0 but I don't know how to move to the next word is while still including this in the output.
A simpler (and 3x faster than the accepted answer) way to use itertools product:
s = 'this is a string'
s2 = s.replace('%', '%%').replace(' ', '%s')
for i in itertools.product((' ', ''), repeat=s.count(' ')):
print(s2 % i)
You can also use itertools.product():
import itertools
s = 'this is a string'
words = s.split()
for t in itertools.product(range(len('01')), repeat=len(words)-1):
print(''.join([words[i]+t[i]*' ' for i in range(len(t))])+words[-1])
Well, it took me a little longer than I expected... this is actually tricker than I thought :)
The main idea:
The number of spaces when you split the string is the length or the split array - 1. In our example there are 3 spaces:
'this is a string'
^ ^ ^
We'll take a binary representation of all the options to have/not have either one of the spaces, so in our case it'll be:
000
001
011
100
101
...
and for each option we'll generate the sentence respectively, where 111 represents all 3 spaces: 'this is a string' and 000 represents no-space at all: 'thisisastring'
def binaries(n):
res = []
for x in range(n ** 2 - 1):
tmp = bin(x)
res.append(tmp.replace('0b', '').zfill(n))
return res
def generate(arr, bins):
res = []
for bin in bins:
tmp = arr[0]
i = 1
for digit in list(bin):
if digit == '1':
tmp = tmp + " " + arr[i]
else:
tmp = tmp + arr[i]
i += 1
res.append(tmp)
return res
def combinations(string):
s = string.split(' ')
bins = binaries(len(s) - 1)
res = generate(s, bins)
return res
print combinations('this is a string')
# ['thisisastring', 'thisisa string', 'thisis astring', 'thisis a string', 'this isastring', 'this isa string', 'this is astring', 'this is a string']
UPDATE:
I now see that Amadan thought of the same idea - kudos for being quicker than me to think about! Great minds think alike ;)
The easiest is to do it recursively.
Terminating condition: Schrödinger join of a single element list is that word.
Recurring condition: say that L is the Schrödinger join of all the words but the first. Then the Schrödinger join of the list consists of all elements from L with the first word directly prepended, and all elements from L with the first word prepended with an intervening space.
(Assuming you are missing thisis astring by accident. If it is deliberately, I am sure I have no idea what the question is :P )
Another, non-recursive way you can do it is to enumerate all numbers from 0 to 2^(number of words - 1) - 1, then use the binary representation of each number as a selector whether or not a space needs to be present. So, for example, the abovementioned thisis astring corresponds to 0b010, for "nospace, space, nospace".

Is there a pythonic way to insert space characters at random positions of an existing 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)
)

Resources