So you just learned about lists and tuples and you’re wondering how they differ?
This is a surprisingly common question.
They both behave in a very similar way.
Both lists and tuples are sequence data types that can store a collection of items.
Each item stored in a list or a tuple can be of any data type.
And you can also access any item by its index.
So the question is, are they different at all?
And if not, why do we have two data types that behave pretty much in the same way?
Can’t we just live with either lists or tuples?
Well, let’s try to find the answer.
The Key Difference between a List and a Tuple
The main difference between lists and tuples is the fact that lists are mutable whereas tuples are immutable.
What does that even mean, you say?
A mutable data type means that a python object of this type can be modified.
An immutable object can’t.
Let’s see what this means in action.
Let’s create a list and assign it to a variable.
>>> a = ["apples", "bananas", "oranges"]
Now let’s see what happens when we try to modify the first item of the list.
Let’s change “apples” to “berries”.
>>> a[0] = "berries"
>>> a
['berries', 'bananas', 'oranges']
Perfect! the first item of a has changed.
Now, what if we want to try the same thing with a tuple instead of a list? Let’s see.
>>> a = ("apples", "bananas", "oranges")
>>> a[0] = "berries"
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment
We get an error saying that a tuple object doesn’t support item assignment.
The reason we get this error is because tuple objects, unlike lists, are immutable which means you can’t modify a tuple object after it’s created.
But you might be thinking, Karim, my man, I know you say you can’t do assignments the way you wrote it but how about this, doesn’t the following code modify a?
>>> a = ("apples", "bananas", "oranges")
>>> a = ("berries", "bananas", "oranges")
>>> a
('berries', 'bananas', 'oranges')
Fair question!
Let’s see, are we actually modifying the first item in tuple a with the code above?
The answer is No, absolutely not.
To understand why, you first have to understand the difference between a variable and a python object.
The Difference Between a Variable and an Object
You are probably confusing variables with objects. This is a very common misconception among beginners.
Remember that a variable is nothing but a reference to the actual python object in memory.
The variable itself is not the object.
For example, let’s try to visualize what happens when you assign a list to a variable a.
>>> a = ["apples", "bananas", "oranges"]
When you do this, a python object of type list is created in the memory and the variable a refers to this object by holding its location in memory.
In fact, you can actually retrieve the location of the list object in memory by inspecting a using the id() function.
>>> a = ["apples", "bananas", "oranges"]
>>> id(a)
4340729544
Now if you modify the first index of the list, and check the id() again, you will get the same exact value because a is still referring to the same object.
>>> a[0] = "berries"
>>> id(a)
4340729544
The following figure shows exactly what happened after the modification.
Now, let’s see what happens if we perform the same thing on tuples.
>>> a = ("apples", "bananas", "oranges")
>>> id(a)
4340765824
>>> a = ("berries", "bananas", "oranges")
>>> id(a)
4340765464
As you can see, the two addresses are different.
This means that after the second assignment, a is referring to an entirely new object.
This figure shows exactly what happened.
Moreover, if no other variables in your program is referring to the older tuple then python’s garbage collector will delete the older tuple from the memory completely.
So there you have it, this concept of mutability is the key difference between lists and tuples.
Mutability is not just a python concept, it is a programming language concept that you will encounter in various programming languages.
But now maybe this whole discussion evokes another question in your head.
Why do we have mutable and immutable objects?
Why Do we need Mutable and Immutable Objects?
Well actually, they both serve different purposes.
Let’s discuss some of the aspects that differentiate between mutable and immutable objects/
1. Appending Performance
Mutability is more efficient when you know you will be frequently modifying an object.
For example, assume you have some iterable object (say x), and you want to append each element of x to a list.
Of course you can just do L = list(x) but under the hood this transforms into a loop that looks like this:
L = []
for item in x:
L.append(item)
This works alright. You keep modifying the list object in place until all the elements of x exist in the list L.
But can you even imagine what would happen if we had used a tuple instead?
T = ()
for item in x:
T = T + (item,)
Can you visualize what is happening in the memory?
Since tuples are immutable, you are basically copying the contents of the tuple T to a new tuple object at EACH iteration.
If the for loop is big, this is a huge performance problem.
Actually, let’s use python to measure the performance of appending to a list vs appending to a tuple when x = range(10000).
This article teaches you how to use the timeit module to measure the execution time of multiple lines of python.
$ python3 -m timeit \
-s "L = []" \
-s "x = range(10000)" \
"for item in x:" " L.append(item)"
1000 loops, best of 3: 1.08 msec per loop
Cool, 1.08 milliseconds.
How about if we do the same thing with tuples?
$ python3 -m timeit \
-s "T = ()" -s "x = range(10000)" \
"for item in x:" " T = T + (item,)"
10 loops, best of 3: 1.63 sec per loop
A whopping 1.63 seconds!
This is a huge performance difference between lists and tuples.
If you want to test your patience, try x = range(1000000).
Now when someone tells you multiple appending to a string object is inefficient, you will understand exactly why (string objects are immutable too in python).
Appending performance: Mutability Wins!
2. Easiness of Debugging
Mutability is cool and all but one thing that can be really annoying with mutable objects is debugging.
What do I mean by that?
Let’s take a look at this very simple example.
>>> a = [1, 3, 5, 7]
>>> b = a
>>> b[0] = -10
>>> a
[-10, 3, 5, 7]
Notice that when we do b = a, we are not copying the list object from b to a.
We are actually telling python that the two variables a and b should reference the same list object.
Because a effectively holds the location of the Python object in memory, when you say b = a you copy that address location (not the actual object) to b.
This results in having two references (a and b) to the same list object.
In other words when we do b[0] = -10, it has the same effect as a[0] = -10.
Of course you can look at the code and rightfully think that it is easy to debug.
Well, you are right for small snippets of code like this, but imagine if you have a big project with many references to the same mutable object.
It will be very challenging to track all the changes to this object because any modification by any of those references will modify the object.
This is not the case with immutable objects even if you have multiple references to them.
Once an immutable object is created, its content will never change.
Easiness of debugging: Immutability Wins!
3. Memory Efficiency
Another benefit of immutability is that it allows the implementation of the language to be more memory efficient.
Let me explain what I mean by that.
In CPython (the most popular implementation of Python) if you create immutable objects that hold the same value, python (under certain conditions) might bundle these different objects into one.
For example, take a look at this code:
>>> a = "Karim"
>>> b = "Karim"
>>> id(a)
4364823608
>>> id(b)
4364823608
Remember that Strings (as well as Integers, Floats, and Bools) are all examples of immutable objects as well.
As you can see, even though in our python program we explicitly created two different string objects, python internally bundled them into one.
How did we know that?
Well because the identity of a is exactly the same as the identity of b.
Python was able to do that because the immutability of strings makes it safe to perform this bundling.
Not only that this will save us some memory (by not storing the string multiple times in memory), but also every time you want to create a new object with the same value, python will just create a reference to the object that already exists in memory which is definitely more efficient.
This concept is called String Interning, and this is an excellent article if you want to dive in deeper.
Not only strings. This also applies to integers (under certain conditions).
>>> a = 1
>>> b = 1
>>> id(a)
4305324416
>>> id(b)
4305324416
That’s pretty cool, isn’t it?
What about tuples though?
CPython until python 3.6 has made the design decision not to automatically bundle two equivalent tuples into one.
>>> a = (1, 2)
>>> b = (1, 2)
>>> id(a)
4364806856
>>> id(b)
4364806920
As you can see, a has a different identity than b.
This design decision makes sense because performing interning for tuples requires making sure that all the tuple items are themselves immutable.
Memory efficiency: Immutability Wins
Conclusion
To understand the difference between python lists and tuples, you must understand the concept of mutability/immutability first.
Lists are mutable objects which means you can modify a list object after it has been created.
Tuples, on the other hand, are immutable objects which means you can’t modify a tuple object after it’s been created.
Both Mutability and Immutability have their own advantages and disadvantages.
Learning Python?
Check out the Courses section!
Featured Posts
- The Python Learning Path (From Beginner to Mastery)
- Learn Computer Science (From Zero to Hero)
- Coding Interview Preparation Guide
- The Programmer’s Guide to Stock Market Investing
- How to Start Your Programming Blog?
Are you Beginning your Programming Career?
I provide my best content for beginners in the newsletter.
- Python tips for beginners, intermediate, and advanced levels.
- CS Career tips and advice.
- Special discounts on my premium courses when they launch.
And so much more…
Excellent
Thanks Suhasini!
wow excellent go on u r perfect
Thanks Ansam! Glad I helped.
I never leave comments on blogs but very nicely written you can tell when someone understands what they are talking about gj!
Thanks Milan. Glad you found it useful.
It’s written so clearly. I understood it all in a go… Good job!
Thanks Suman!
Thank you for such a great article. However, I was wondering what are the advantages of tuples? Like when should we create a tuple instead of list.
Thanks Saksham! Good question. In general, most of the time I wouldn’t really overthink it. That said, if you know that your object is immutable, use tuples. Otherwise, use lists.
I know it might not be beginner’s thing, but would be worth adding that if a tuple contains variables that are referencing mutable objects – while you can’t change those variables, you can change the objects referenced by them (as you’re not changing the reference itself) eg.:
aList = [“a”,”b”,”c”]
aTuple = (1,aList,”d”) # aTuple >> (1, [‘a’, ‘b’, ‘c’], ‘d’)
aTuple[1][0]=”X” # aTuple >> (1, [‘X’, ‘b’, ‘c’], ‘d’)
Very good point! Thank you. I will make sure to add this to the article when I have time.
This was one Superb article about Mutability and Immutability.
Loved it.
Thank you Divyang!
awesome article, interactive and helpful
I think this line is incorrect! “Immutability is more efficient when you know you will be frequently modifying an object”
It should be mutability
Thanks! I fixed it.
Very good article for beginners to understand the concept, thank you.
You are very welcome Srinath!
When something is written at such a basic level that most anyone can understand, it really speaks volumes about the person’s understanding who wrote it. Thank you so much for this explanation between Tuples and Lists.
Thank you 🙂
You explained it very well. Thank you
Thanks karim ,I was confused in tuple and list but u explained very clearly with example…thanks again and keep it up
This was one of the best explanation I ever saw. Great job. Keep up the work !!!!!
Thank you Jagruthi!
I understand the advantages of using immutable objects instead of mutable ones when using Stirngs, Floats etc. But, in the case of tuples, as there is no bundle for identical tuples, I don’t see which is the advantage. My impression is that one should always use list instead, because tuples are not more effcient than lists in terms of memory and cannot be changed. Am I missing something?
In terms of memory efficiency, you are right. But this is just an implementation detail. In other words, CPython decided not to implement interning for tuples but there is nothing in the Python programming language that stipulates that. In my opinion, I always prefer using immutable objects if I know that the objects are not going to be modified. Mutable objects sometimes lead to unexpected behavior if you are not careful. For example: >>> x = [[]]*10 >>> x [[], [], [], [], [], [], [], [], [], []] >>> x[0].append(5) >>> x [[5], [5], [5], [5], [5], [5], [5],… Read more »
well done
Karim my man, thank you for this great explanation!
You are very welcome!
This is by far the BEST explanation I have come across.
Kudos brother!
Thanks Ravi!
Excellent!
very well explained. I appreciate it very much.
what an answer!
Thanks Mosaab!
I never leave a reply. This is my first. great explanation!
Thanks Cameron
nicely explained
Great explanation! Best I’ve seen.
Thanks Aaron!
perfect,
thank you.
Excellent and crystal clear explanation..!! Thank you!!
This is the superb explanation I have ever seen! Very thoughtful article.Thank you so much.
Thank YOU!
Oh Man! you are just amazing.
Perfection 🙂
Thanks Babar!
Nice explained for beginners. Thank you
You are very welcome!
Excellent article! nice explanation
Thanks Surendhar!
Excellent write-up, very simple and precisely explained. Thanks
Thank you Yuva!
Thank you Karim. Well written! Found it very useful.
Thank you for stopping by Manivannan 🙂
Crystal Clear. Thank you 🙂
crystal clear
Very good explanation Karim
Thanks!
Very well explained. A beginner in Python, like me, can definitely understand everything when laid out like this, Thank you very much.
I am glad you found the article useful, Laura!
This was great, to the point, and very informative! Thanks!
You are welcome!
first comment ever on a blog.. damn you are awesome. understood every single word. RESPECT.
edit: subscribing to your thing:-)
Thank you Akash and welcome to the newsletter 🙂
very clear thank you
Thanks!
I rarely comment. This is the best basic Python article I have read. Cheers.
Thanks!
Thanks
Thanks!
This was super easy to understand!!
You are bookmarked and add blocker removed.
Best
Very good explanation… Proper knowledge for beginnner… And Thanks…
I am a beginner and I have been struggling with this for a while to understand what’s the difference. Both Lists and Tuple , I can somehow do similar operations. But you’r blog is a life savior , now I can sleep 🙂
Good night haha
Beautifully explained. And entertaining to read, too. Bless you Karim!
Thanks so much, Haritha.
Explanation is very good and detailed… Perfect for beginners.. after reading it though of leaving my comment.. this is my first comment.. never wrote any comments till now… you are so good at teaching..
Thanks Zaara. I am glad you found it useful!
its was amazing , the way of delivery and understanding was too good
That is kind of you. Thanks!
very well explained. made the concepts so easy to understand. Great work!
Thanks Poulomi!
Good article. Easy to understand. Great work
Hey Karim, this is great, really helped me in understanding these concepts better. Thanks.
Thank You Man!