Torsten Mohr wrote:
But i think my understanding was wrong (though it is not yet clear). If i hand over a large string to a function and the function had the possibility to change it, wouldn't that mean that it is necessary to hand over a _copy_ of the string? Else, how could it be immutable?
Anything which might change the string, can only do so by returning a *new* string.
>>> a = "My first string" >>> b = a.replace('first', 'second') >>> b 'My second string' >>> a 'My first string' >>>
Saying that strings are immutable means that, when 'a' is pointing to a string, the (string) object that 'a' points to will always be the same. (Unless 'a' is re-bound, or someone uses some deep black magic to change things "behind the scenes"...) No method that I call on 'a', or function that I pass 'a' to, can alter that object -- it can only create a new object based off of the original. (You can demonstrate this by checking the id() of the objects.)
Mutable objects, on the other hand, can change in place. In the case of lists, for example, it will stay the same list object, but the list contents can change.
Note, also, that passing a string into a function does not copy the string; it creates a new name binding (i.e. reference) to the same object.
>>> def func(item): ... print "Initial ID:", id(item) ... item = item.replace('first', 'second') ... print "Resulting ID:", id(item) ... >>> id(a) 26278416 >>> func(a) Initial ID: 26278416 Resulting ID: 26322672 >>> id(a) 26278416 >>>
Thinking about all this i came to the idea "How would i write a function that changes a string with not much overhead?".
Since strings cannot really be changed, you simply try to minimize the number of new strings created. For example, appending to a string inside of a for-loop creates a new string object each time, so it's generally more efficient to convert the string to a list, append to the list (which doesn't create a new object), and then join the list together into a string.
def func(s): change s in some way, remove all newlines, replace some charaters by others, ... return s
s = func(s)
This seems to be a way to go, but it becomes messy if i hand over lots of parameters and expect some more return functions.
This has the advantage of being explicit about s being (potentially) changed. References, in the way that you mean them, are even messier in the case of numerous parameters because *any* of those parameters might change. By simply returning (new) objects for all changes, the function makes it very clear what's affected and what isn't.
Jeff Shannon Technician/Programmer Credit International
-- http://mail.python.org/mailman/listinfo/python-list