Python: How do I pass a string by reference?

Question:

From this link: How do I pass a variable by reference?, we know, Python will copy a string (an immutable type variable) when it is passed to a function as a parameter, but I think it will waste memory if the string is huge. In many cases, we need to use functions to wrap some operations for strings, so I want to know how to do it more effective?

Asked By: halostack

||

Answers:

Python does not make copies of objects (this includes strings) passed to functions:

>>> def foo(s):
...     return id(s)
...
>>> x = 'blah'
>>> id(x) == foo(x)
True

If you need to “modify” a string in a function, return the new string and assign it back to the original name:

>>> def bar(s):
...     return s + '!'
...
>>> x = 'blah'
>>> x = bar(x)
>>> x
'blah!'

Unfortunately, this can be very inefficient when making small changes to large strings because the large string gets copied. The pythonic way of dealing with this is to hold strings in an list and join them together once you have all the pieces.

Answered By: Steven Rumbalski

Just pass it in as you would any other parameter. The contents won’t get copied, only the reference will.

Answered By: NPE
In [7]: strs="abcd"

In [8]: id(strs)
Out[8]: 164698208

In [9]: def func(x):
    print id(x)
    x=x.lower() #perform some operation on string object, it returns a new object
    print id(x)
   ...:     

In [10]: func(strs)
164698208              # same as strs, i.e it actually passes the same object 
164679776              # new object is returned if we perform an operation
                       # That's why they are called immutable  

But operations on strings always return a new string object.

Answered By: Ashwini Chaudhary
def modify_string( t ):
  the_string = t[0]
  # do stuff

modify_string( ["my very long string"] )
Answered By: Jakub M.

Python does pass a string by reference. Notice that two strings with the same content are considered identical:

a = 'hello'
b = 'hello'
a is b        # True

Since when b is assigned by a value, and the value already exists in memory, it uses the same reference of the string. Notice another fact, that if the string was dynamically created, meaning being created with string operations (i.e concatenation), the new variable will reference a new instance of the same string:

c = 'hello'
d = 'he'
d += 'llo'
c is d        # False

That being said, creating a new string will allocate a new string in memory and returning a reference for the new string, but using a currently created string will reuse the same string instance. Therefore, passing a string as a function parameter will pass it by reference, or in other words, will pass the address in memory of the string.

And now to the point you were looking for- if you change the string inside the function, the string outside of the function will remain the same, and that stems from string immutability. Changing a string means allocating a new string in memory.

a = 'a'
b = a    # b will hold a reference to string a
a += 'a'
a is b   # False

Bottom line:

You cannot really change a string. The same as for maybe every other programming language (but don’t quote me).
When you pass the string as an argument, you pass a reference. When you change it’s value, you change the variable to point to another place in memory. But when you change a variable’s reference, other variables that points to the same address will naturally keep the old value (reference) they held.
Wish the explanation was clear enough

Answered By: Shay Yzhakov

If you want to potentially change the value of something passed in, wrap it in a dict or a list:

This doesn’t change s

def x(s):
  s += 1

This does change s:

def x(s):
  s[0] += 1

This is the only way to “pass by reference”.

Answered By: Erik Aronesty

wrapping the string into a class will make it pass by reference:

    class refstr:
       "wrap string in object, so it is passed by reference rather than by value"
       def __init__(self,s=""):
          self.s=s
       def __add__(self,s):
          self.s+=s
          return self
       def __str__(self):
          return self.s

    def fn(s):
       s+=" world"

    s=refstr("hello")
    fn(s) # s gets modified because objects are passed by reference
    print(s) #returns 'hello world' 
Answered By: Peter Kronegger
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.