Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are python strings and tuples are made immutable?

I am not sure why strings and tuples were made to be immutable; what are the advantages and disadvantage of making them immutable?

like image 250
user186477 Avatar asked Oct 08 '09 15:10

user186477


People also ask

Why are strings in Python immutable?

In Python, strings are made immutable so that programmers cannot alter the contents of the object (even by mistake). This avoids unnecessary bugs. Some other immutable objects are integer, float, tuple, and bool. More on mutable and immutable objects in Python.

Are strings and tuples immutable?

Immutable objects include numbers, strings and tuples. Such an object cannot be altered. A new object has to be created if a different value has to be stored." The official Python documentation (and every other book, tutorial, and StackOverflow answer I've found) describes tuples as immutable.

Why tuple is immutable in Python with example?

Unlike lists, tuples are immutable. This means that elements of a tuple cannot be changed once they have been assigned. But, if the element is itself a mutable data type like a list, its nested items can be changed. We can also assign a tuple to different values (reassignment).

How are Python tuples immutable?

Tuples are immutable Besides the different kind of brackets used to delimit them, the main difference between a tuple and a list is that the tuple object is immutable. Once we've declared the contents of a tuple, we can't modify the contents of that tuple.


2 Answers

Imagine a language called FakeMutablePython, where you can alter strings using list assignment and such (such as mystr[0] = 'a')

a = "abc" 

That creates an entry in memory in memory address 0x1, containing "abc", and the identifier a pointing to it.

Now, say you do..

b = a 

This creates the identifier b and also points it to the same memory address of 0x1

Now, if the string were mutable, and you change b:

b[0] = 'z' 

This alters the first byte of the string stored at 0x1 to z.. Since the identifier a is pointing to here to, thus that string would altered also, so..

print a print b 

..would both output zbc

This could make for some really weird, unexpected behaviour. Dictionary keys would be a good example of this:

mykey = 'abc' mydict = {     mykey: 123,     'zbc': 321 }  anotherstring = mykey anotherstring[0] = 'z' 

Now in FakeMutablePython, things become rather odd - you initially have two keys in the dictionary, "abc" and "zbc".. Then you alter the "abc" string (via the identifier anotherstring) to "zbc", so the dict has two keys, "zbc" and "zbc"...

One solution to this weirdness would be, whenever you assign a string to an identifier (or use it as a dict key), it copies the string at 0x1 to 0x2.

This prevents the above, but what if you have a string that requires 200MB of memory?

a = "really, really long string [...]" b = a 

Suddenly your script takes up 400MB of memory? This isn't very good.

What about if we point it to the same memory address, until we modify it? Copy on write. The problem is, this can be quite complicated to do..

This is where immutability comes in.. Instead of requiring the .replace() method to copy the string from memory into a new address, then modify it and return.. We just make all strings immutable, and thus the function must create a new string to return. This explains the following code:

a = "abc" b = a.replace("a", "z") 

And is proven by:

>>> a = 'abc' >>> b = a >>> id(a) == id(b) True >>> b = b.replace("a", "z") >>> id(a) == id(b) False 

(the id() function returns the memory address of the object)

like image 69
dbr Avatar answered Oct 04 '22 14:10

dbr


One is performance: knowing that a string is immutable makes it easy to lay it out at construction time — fixed and unchanging storage requirements. This is also one of the reasons for the distinction between tuples and lists. This also allows the implementation to safely reuse string objects. For example, the CPython implemenation uses pre-allocated objects for single-character strings, and usually returns the original string for string operations that doesn’t change the content.

The other is that strings in Python are considered as "elemental" as numbers. No amount of activity will change the value 8 to anything else, and in Python, no amount of activity will change the string “eight” to anything else.

https://web.archive.org/web/20201031092707/http://effbot.org/pyfaq/why-are-python-strings-immutable.htm

like image 25
Nasir Avatar answered Oct 04 '22 16:10

Nasir