While I tried to execute the following code, I faced some problem in loop iterations and couldn't figure out what's the problem might be.
def string_splosion(s):
"""Takes a non-empty string s like "Code" and
returns a string like "CCoCodCode"
"""
for i in range(len(s)):
return s[i] * (i+1)
print(string_splosion('Code'))
you leave the function after the first return.
I think this would be the right solution
def string_splosion(s):
result = ''
for i in range(len(s)):
result += s[:i]
result += s
return result
if you have return inside in a loop the loop is raning only for one time.
def string_splosion(s):
"""Takes a non-empty string s like "Code" and
returns a string like "CCoCodCode"
"""
a='' ## empty String
for i in range(len(s)):
a += s[0:i] +s[i] ## this is beter way to do this "CCoCodCode"
return a ## out of the "for" loop
print(string_splosion('Code'))
Try something like:
def string_splosion(s):
return ''.join(s[:i+1] for i in range(len(s)))
print(string_splosion('Code'))
Related
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
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))
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)
The question is :
Given a string, return a string where for every char in the original, there are two chars.
This is my attempt:
def double_char(str):
n = 0
for x in range(0, len(str)):
return 2*str[n]
n = n+1
When I run it, it only returns 2 versions of the first letter and doesn't loop properly. So for double_char(Hello) it just returns HH.
What is going wrong? Thanks in advance for any help, sorry for the really beginner question.
The return is causing your function to return in the first iteration so it just returns 2 of the first letter.
What you may have intended to write was something like
def double_char(s):
n = 0
r = ''
for x in range(0, len(s)):
r += 2*s[n]
n = n+1
return r
Building a string incrementally that is just 2 of each character.
A neater refactor of that function (without duplicating the other answer by using a comprehension) is
def double_char(s):
r = ''
for c in s:
r += 2*c
return r
You also should not use str as a variable name. It is a built in type and you are hiding that by defining a variable called str.
return returns control to the caller once reached, thus exiting your for loop prematurely.
Here's a simpler way to do that with str.join:
def double_char(s):
return ''.join(i*2 for i in s)
>>> s = 'Hello'
>>> double_char(s)
'HHeelllloo'
Do not use str as name to avoid shadowing the builtin str function.
Here is a different way to solving the question.
def double_char(str):
new_str = ""
for i in range(len(str)):
new_str += (str[i]*2)
return new_str
double_char('Hello')
'HHeelllloo'
def double_char(str):
string = ''
for i in range(len(str)):
string += str[i] * 2
i += 1
return string
I'm trying to write a function that joins a list of elements and then returns that join without the last character.
This is what I have so far:
n = ["Andy", "Warhol"]
def littery(word):
total = ''
for i in range(len(word)):
total = total + word[i]
return total
littery(n)
a = littery(n)[0:len(littery(n))-1]
print
The program prints: AndyWarho
Is there a better way to do this? I want to do this inside the function, without using: a = littery(n)[0:len(littery(n))-1]
If I understand what you're trying to do correctly, you can just do this:
def littery(lst):
return ''.join(lst)[:-1]
>>> littery(['Andy', 'Warhol'])
'AndyWarho'
Or if you want to take the last element off of each element of lst, you could do this:
def littery(lst):
return ''.join(word[:-1] for word in lst)
>>> littery(['Andy', 'Warhol'])
'AndWarho'
Or if you don't want to build a list in the call, you can do this:
def littery(*lst):
return ''.join(lst)[:-1]
>>> littery('Andy', 'Warhol')
'AndyWarho'
Or if you want to do it another way, you can do this:
def littery(*lst):
return ''.join(lst[:-1] + [lst[-1][:-1]])
Or if you might need the slice again at some point:
last = slice(-1)
def littery(*lst):
return ''.join(lst)[last]