Break a string and reverse each element of it - python

I'm learning data and algorithm, here is the question I met
Question:Write a short recursive Python function that takes a character string s and
outputs its reverse. For example, the reverse of pots&pans would be
snap&stop .
a="pots&pans"
b=a.split("&")
c=[]
c=list(b)
def reverse(data,leng,leng2,index,count):
rev=(leng-1)-count
if count<leng/2:
temp=data[index][count]
data[index][count]=data[index][rev]
data[index][rev]=temp
if index==leng2:
print(data[index-1]+"&"+data[index])
return reverse(data,leng,leng2,index+1,count)
reverse(c,4,2,0,0)
I got an error here
TypeError: 'str' object does not support item assignment
My initial thought is that str is immutable. So it is better to store it in an list and do the operations. However, it met some problem when I trying to assign str to a list. Any solution to this?

Try this:
a="pots&pans"
b=a.split("&")
def reverse(word):
if not word:
return ""
return reverse(word[1:]) + word[0]
result = reverse(b[1]) + "&" + reverse(b[0])
print(result)
If you want one recursion to also reverse all the words position:
a="pots&pans&hello&hi"
b=a.split("&")
def reverse(lis):
if not lis:
return ""
if type(lis) == list and len(lis) == 1:
return reverse(lis[0])
if type(lis) == str:
return reverse(lis[1:]) + lis[0]
if type(lis) == list:
return reverse(lis[1:]) + "&" + reverse(lis[0])
print(reverse(b))

One recursive approach would be to append the first character to the reverse of the rest of the string:
def rev(s): return rev(s[1:])+s[0] if s else ""
output:
rev("pots&pans")
'snap&stop'
You could also do this without indexing using parameter unpacking:
def rev(first,*rest): return rev(*rest)+first if rest else first
rev(*"pots&pans")
'snap&stop'

Try this:
a="pots&pans"
def reverse(a_string):
`letter_list = list(a_string)`
`letter_list.reverse()`
`return(''.join(letter_list))`
print(reverse(a))

Related

int object is not iterable adding two lists

The aim is to add two given lists through recursion. For example
[1,2,3] + [4,5,6] = [5,7,9]
I am getting an
int object is not iterable
error.
Here is the code:
def seqaddr(l1,l2):
if len(l1)==1:
l1[0]=l1[0]+l2[0]
return l1
else:
return seqaddr(l1[:len(l1)-1],l2[:len(l2)-1]) + list(l1.pop()+l2.pop())
seqaddr([1,2,3],[4,5,6])
You can't convert an number to a list using list(n). You should use a list literal. Change the following line:
return seqaddr(l1[:len(l1)-1],l2[:len(l2)-1]) + list(l1.pop()+l2.pop())
to
return seqaddr(l1[:len(l1)-1],l2[:len(l2)-1]) + [l1.pop() + l2.pop()]
Update: Your function mutates the original arguments, which is generally considered a Bad Thing™. An idempotent version can be written as:
def seqaddr(l1, l2):
if len(l1) == 1:
return [l1[0] + l2[0]]
else:
return seqaddr(l1[:-1], l2[:-1]) + [l1[-1] + l2[-1]]
A further simplification to the last line of code in the answer by Selcuk
def seqaddr(l1,l2):
if len(l1)==1:
l1[0]=l1[0]+l2[0]
return l1
else:
return seqaddr(l1[:-1],l2[:-1]) + [l1.pop() + l2.pop()]

Why isn't my return command being obeyed?

I'm trying to write a function to return the longest common prefix from a series of strings. Using a debugger, saw that my function reaches the longest common prefix correctly, but then when it reaches the statement to return, it begins reverting to earlier stages of the algorithm.
For test case strs = ["flower","flow","flight"]
The output variable holds the following values:-
f > fl > f
instead of returning fl.
Any help would be appreciated, because I don't really know how to Google for this one. Thank you.
class Solution(object):
def longestCommonPrefix(self, strs, output = ''):
#return true if all chars in string are the same
def same(s):
return s == len(s) * s[0]
#return new list of strings with first char removed from each string
def slicer(list_, list_2 = []):
for string in list_:
string1 = string[1:]
list_2.append(string1)
return list_2
#return string containing first char from each string
def puller(list_):
s = ''
for string in list_:
s += string[0]
return s
#pull first character from each string
s = puller(strs)
#if they are the same
#add one char to output
#run again on sliced list
if same(s):
output += s[0]
self.longestCommonPrefix(slicer(strs), output)
return output
This can be handled with os.path.commonprefix.
>>> import os
>>> strs = ["flower","flow","flight"]
>>> os.path.commonprefix(strs)
'fl'
It doesn't "revert". longestCommonPrefix potentially calls itself - what you're seeing is simply the call-stack unwinding, and flow of execution is returning to the calling code (the line that invoked the call to longestCommonPrefix from which you are returning).
That being said, there's really no need to implement a recursive solution in the first place. I would suggest something like:
def get_common_prefix(strings):
def get_next_prefix_char():
for chars in zip(*strings):
if len(set(chars)) != 1:
break
yield chars[0]
return "".join(get_next_prefix_char())
print(get_common_prefix(["hello", "hey"]))
You are looking at the behavior...the final result...of recursive calls to your method. However, the recursive calls don't do anything to affect the result of the initial execution of the method. If we look at the few lines that matter at the end of your method:
if same(s):
output += s[0]
self.longestCommonPrefix(slicer(strs), output)
return output
The problem here is that since output is immutable, its value won't be changed by calling longestCommonPrefix recursively. So from the standpoint of the outermost call to longestCommonPrefix, the result it will return is determined only by if same(s) is true or false. If it is true it will return s[0], otherwise it will return ''.
The easiest way to fix this behavior and have your recursive call affect the result of the prior call to the method would be to have its return value become the value of output, like this:
if same(s):
output += s[0]
output = self.longestCommonPrefix(slicer(strs), output)
return output
This is a common code pattern when using recursion. Just this change does seem to give you the result you expect! I haven't analyzed your whole algorithm, so I don't know if it becomes "correct" with just this change.
Can you try this? I
class Solution(object):
def longestCommonPrefix(self, strs, output = ''):
#return true if all chars in string are the same
def same(s):
return s == len(s) * s[0]
#return new list of strings with first char removed from each string
def slicer(list_, list_2 = []):
for string in list_:
string1 = string[1:]
list_2.append(string1)
return list_2
#return string containing first char from each string
def puller(list_):
s = ''
for string in list_:
s += string[0]
return s
#pull first character from each string
s = puller(strs)
# Can you Try this revision?
# I think the problem is that your new version of output is being lost when the fourth called function returns to the third and the third returns to the second, etc...
# You need to calculate a new output value before you call recursively, that is true, but you also need a way to 'store' that output when that recursively called function 'returns'. Right now it disappears, I believe.
if same(s):
output += s[0]
output = self.longestCommonPrefix(slicer(strs), output)
return output

replace all but the last five characters of a given string into "*" and returns the new masked string

I have returned the correct answer by breaking up the string in the maskString function. However, I was wondering how to do the same with a loop? using add/join when the desired indexed is reached and new string formed. my attempt is the maskString2 function. Any ideas?? tried with 'join' instead of '+'.
def maskString(self, string):
return '*'*(len(string)-5) + string[-5:]
def maskString2(self,string):
new_string = string[:-5]
for i in new_string:
new_string.replace(i, '*')
return new_string + string[-5:]
This is an easy to understand approach:
def maskString(self, string):
lst = list(string)
for i in range(0,len(lst)-5):
lst[i] = '*'
s = ''.join(lst))
return(s)
Assuming that the length of string is always greater than 5

python simple loop_.join function

I'm an amateur learner and would like to have more ideas on these.
This is what I want,
paper_doll('Hello') --> 'HHHeeellllllooo'
Here is my code and it doesn't work, but I have no ideas why.
def paper_doll(text):
for i in range(0,len(text)-1):
return ''.join(text[i]*3)
paper_doll('Hello')
The result became 'HHH'.
Understood the following would work,
def paper_doll(text):
result = ''
for char in text:
result += char * 3
return result
But why .join doesn't work in this case?
def paper_doll(text):
ret=[]
for i in text:
ret.append(i*3)
return ''.join(ret)
Should work. This returns each 3 letter iteration, joined together.
First, your code does not work because the return statement exits from the function on the first iteration loop, so it triples only the first letter, and that's all:
def paper_doll(text):
for i in range(0,len(text)-1): # on 1st iteration: i = 0
return ''.join(text[i]*3) # on 1st iteration: text[i] equals 'H' ==> 'HHH' is returned
Secondly, here is a solution using comprehension, which is well adapted in your case to iterate over each character of a string:
def paper_doll(text):
return ''.join(i*3 for i in text)
print(paper_doll('Hello')) # HHHeeellllllooo
Your initial problem was the return in your iteration. This short circuits the rest of the loop... as noted in other answers.
python can iterate through a string for you. Another answer using list comprehension:
def paper_doll(text):
return ''.join([char*3 for char in text])
Add to a string during the loop, return the result:
def paper_doll(text):
s = ''
for i in range(0,len(text)):
s += ''.join(text[i]*3)
return s
print(paper_doll('Hello'))
Output:
HHHeeellllllooo
(I also removed the -1 in range so you get three "o"s)

Python: can a function return a string?

I am making a recursive function that slices string until it is empty. When it is empty it alternatively selects the characters and is supposed to print or return the value. In this case I am expecting my function to return two words 'Hello' and 'World'. Maybe I have got it all wrong but what I don't understand is that my function doesn't let me print or return string. I am not asking for help but I'd like some explanation :) thanks
def lsubstr(x):
a= ''
b= ''
if x == '':
return ''
else:
a = a + x[0:]
b = b + x[1:]
lsubstr(x[2:])
#print (a,b)
return a and b
lsubstr('hweolrllod')
so I changed my code to this:
def lsubstr(x):
if len(x) <1:
return x
else:
return (lsubstr(x[2:])+str(x[0]),lsubstr(x[2:])+str(x[1]))
lsubstr('hweolrllod')
and what I am trying to make is a tuple which will store 2 pairs of characters and concatenate the next ones,
the error I get is
TypeError: Can't convert 'tuple' object to str implicitly
what exactly is going wrong, I have checked in visualization, it has trouble in concatenating.
The and keyword is a boolean operator, which means it compares two values, and returns one of the values. I think you want to return a tuple instead, like this:
...
return (a, b)
And then you can access the values using the indexing operator like this:
a = lsubstr( ... )
a[0]
a[1]
Or:
word1, word2 = lsubstr( ... )

Categories