Reputation: 125
For the below code, even though reverse(s)
returns the reversed string, the string itself is not reversed.
s = ["h", "e", "l", "l", "o"]
def reverse(s):
if len(s) == 0:
return
if len(s) == 1:
return s;
temp = s[0]
s = reverse(s[1:])
s.append(temp)
return s
print(reverse(s))
print(s)
Output
['o', 'l', 'l', 'e', 'h'] #reverse(s)
['h', 'e', 'l', 'l', 'o'] #s
As per this, Python: How do I pass a string by reference?. I understand i need to set s= reverse(s)
and then the list gets reversed and this works alright.
But why is s
getting reversed for this one?
s = ["h", "e", "l", "l", "o"]
def reverse(s, index):
if index >= len(s) or len(s) == 0:
return
reverse(s, index + 1)
s.insert((len(s) - 1 - index), s.pop())
reverse(s, 0)
print(s)
Output
['o', 'l', 'l', 'e', 'h']
While debugging I have found out that for the first piece of code when the handle comes back to the print statement, s
becomes the original list, but for the second piece of code, s
remains reversed. I am not sure what is happening here
Any help is appreciated!
Upvotes: 2
Views: 129
Reputation: 140148
The first method never changes the original s
argument, as it slices it (using s[0]
and s[1:]
), thus making copies (and when you're calling s.append(temp)
, s
is already a copy)
The second method keeps changing the original s
argument (with s.pop()
and s.insert()
)
If you want to avoid that the second method changes the original argument, create a wrapper method that creates a copy beforehand (which also avoids showing the auxiliary index argument)
def reverse(s):
def internal_reverse(s, index):
if index >= len(s) or len(s) == 0:
return
internal_reverse(s, index + 1)
s.insert((len(s) - 1 - index), s.pop())
s2 = s[:] # s[:] is a way to copy the input
internal_reverse(s2, 0)
return s2
Upvotes: 3