-2

I was trying in-place reverse string problem from leetcode.

This was my simple solution:

def reverseString(s):
    s = s[::-1]

But it does not change the input string at all:

>>> s = ['f','h','y','5']
>>> reverseString(s)
>>> s 
['f', 'h', 'y', '5']

As you can see, it did not reverse the input string in-place. So, then I tried following

>>> s = ['f','h','y','5']
>>> s = s[::-1]
>>> s
['5', 'y', 'h', 'f']

So the code inside method body does indeed reverse the string, but the method does not. Q1. Why is this so?

Update

I also realize that changing s to s[:] in function makes it work as desired:

def reverseString(s):
    s[:] = s[::-1] 

>>> s = ['f','h','y','5']
>>> reverseString(s)
>>> s 
['5', 'y', 'h', 'f']

Q2. Why is this so?

Update 2

def reverseString1(s):
    print('reverseString1 ================ ')
    print('----> ', id(s))
    s = s[::-1]
    print(id(s))
    print('----> ', id(s))
    print('=============================== ')

def reverseString2(s):
    print('reverseString2 ================ ')
    print('----> ', id(s))
    s[:] = s[::-1]
    print('=============================== ')

s  = ['a','b','c']
print('----> ', id(s))
reverseString1(s)
print('----> ', id(s))
print(s)
reverseString2(s)
print(s)
print('----> ', id(s))

Output

---->  1279622944512
reverseString1 ================ 
---->  1279622944512
1279623002048
---->  1279623002048
===============================
---->  1279622944512
['a', 'b', 'c']
reverseString2 ================
---->  1279622944512
===============================
['c', 'b', 'a']
---->  1279622944512

I believe this output does prove that the issue is not with name binding while calling function, but the why s = s[::-1] creates new instance VS why s[:] = s[::-1] doesnt create new instance. The question can be reopned.

Rnj
  • 641
  • 1
  • 2
  • 13
  • Also: https://stackoverflow.com/questions/575196/why-can-a-function-modify-some-arguments-as-perceived-by-the-caller-but-not-oth – luk2302 May 27 '22 at 07:16
  • 1
    Note that your `s` is a **list** (i.e. mutable), this would fail with an actual string: `reverseString('abc')` – mozway May 27 '22 at 07:27
  • yes I realize that, for string, second version of `reverseString` gives `TypeError: 'str' object does not support item assignment`. But (for string `abc`) even first version does not reverse string in caller, apparently because strings are immutable. But why behavior of these two versions differ for list `['a','b','c']` ? I checked by printing `id()`. For list, first version i.e. `s=s[::-1]` creates new instance while second version modifies existing instance. Why is this so? So this also implies that the problem is not related to name binding and question might need to reopened. – Rnj May 27 '22 at 07:48
  • Have you read the duplicates above? TL;DR: `s = ...` just assigns a value to a variable, in this case a function-local variable, and that will *never* be seen by anyone outside the function. In case of `s[:] = ...`, you're *mutating* an object, and that *will* be seen by anyone holding a reference to that object. – deceze May 27 '22 at 07:56

0 Answers0