Lately, I’ve been thinking about new Python topics to write about, so I took to Google. When I searched “Python how to”, “Python how to add to a list” popped up first. Since this must be a popular search term, I decided it was worth an article. In other words, today we’ll learn how to add an item to a list in Python.
To save you some time, you can start adding items to a list right now with the append()
method: my_list.append(item)
. If you have more complex needs, consider using extend()
, insert()
, or even slice assignment. See the rest of the article for more details.
Table of Contents
Problem Description
For people who come from other programming languages, tasks like creating and adding to a list can be daunting. After all, almost every language supports lists in one form or another (e.g. arrays, lists, etc.), but not all languages have the same syntax. For instance, here’s an example of an array in Java:
int[] myArray = new int[10]; myArray[0] = 5; // [5, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Here, we’ve created a fixed-size array of 10 elements, and we’ve set the first element to 5. In other words, we don’t really add elements to arrays in Java. Instead, we modify existing elements.
Meanwhile, in a language like Rust, arrays are declared a little differently:
let mut my_array: [i32; 10] = [0; 10]; my_array[0] = 5; // [5, 0, 0, 0, 0, 0, 0, 0, 0, 0]
In Rust, we have to explicitly declare the array as mutable with mut
. That way, we can modify the array just like in Java. In addition, the syntax is quite a bit different. For example, we set the type to i32
, the size to 10, and all elements to 0.
Of course, there are languages with built-in lists much similar to what you might find in Python. For example, Ruby’s (dynamic) arrays can be created and modified as follows:
my_array = [] my_array << 5 # [5]
Unlike the previous solution, we didn’t have to setup our array with a certain size. Instead, we’re able to start with an empty array. Then, we pushed a 5 into the array, and called it a day.
Oddly enough, in Python, the syntax for creating a list is quite similar:
my_list = []
But, how do we add anything to this list? That’s the topic of this article.
Solutions
In this section, we’ll take a look at various ways to add an item to a list in Python. Since this task is pretty straightforward, there aren’t very many options. In fact, that’s sort of by design in Python (i.e. “There should be one– and preferably only one –obvious way to do it.”). That said, I’ve included a few silly solutions to keep this piece interesting.
Add an Item to a List Statically
To be honest, this is sort of a nonanswer. That said, if you want to populate a list, you can declare the elements statically:
my_list = [2, 5, 6]
Rather than adding the items one at a time, we’ve decided to initialize the list exactly as we want it to appear. In this case, we’ve created a list with three items in it: 2, 5, and 6.
Interestingly, we can actually “add” an item to this list by using the indices directly:
my_list[0] = 4 # [4, 5, 6]
In this example, we’ve replaced the element at the first position with a 4. In the next section, we’ll look at other ways to modify an existing list.
Add an Item to a List by Slice Assignment
In Python, there is this very peculiar piece of syntax that I only just recently learned about called slice assignment. While slicing can be used to return a section of a list, slice assignment can be used to replace a section of a list. In other words, it’s possible to write an expression which adds a value to the end of a list:
my_list = [] my_list[len(my_list):] = [5]
Here, we have an expression which replaces the end of the list, which is an empty list, with a list containing a single value. In essence, we’ve added an item to the end of the list.
Interestingly enough, this syntax can be used to replace any part of a list with any other list. For example, we could add an item to the front of the list:
my_list = [1, 2, 3, 4] my_list[:0] = [0] # [0, 1, 2, 3, 4]
Likewise, we can replace any sublist with any other list of any size:
my_list = [1, 2, 3, 4] my_list[:2] = [6, 7, 8, 9] # [6, 7, 8, 9, 3, 4]
Fun fact: we aren’t restricted to lists with this syntax. We can assign any iterable to the slice:
my_list = [] my_list[:] = "Hello" # ['H', 'e', 'l', 'l', 'o'] my_list[:] = (1, 2, 3) # [1, 2, 3] my_list[:] = (i for i in range(5)) # [0, 1, 2, 3, 4]
When I first added this solution to the list, I thought it was kind of silly, but now I’m seeing a lot of potential value in it. Let me know if you’ve ever used this syntax and in what context. I’d love to see some examples of it in the wild.
Add an Item to a List with Append
On a more traditional note, folks who want to add an item to the end of a list in Python can rely on append:
my_list = [] my_list.append(5)
Each call to append will add one additional item to the end of the list. In most cases, this sort of call is made in a loop. For example, we might want to populate a list as follows:
my_list = [] for i in range(10): my_list.append(i)
Of course, if you’re going to do something like this, and you’re not using an existing list, I recommend using a list comprehension:
my_list = [i for i in range(10)]
At any rate, append()
is usually the go-to method for adding an item to the end of a list. Of course, if you want to add more than one item at a time, this isn’t the solution for you.
Add an Item to a List with Extend
If you’re looking to combine two lists, extend()
is the method for you:
my_list = [] my_list.extend([5])
In this example, we append a list of a single element to the end of an empty list. Naturally, we can append a list of any size:
my_list = [3, 2] my_list.extend([5, 17, 8]) # [3, 2, 5, 17, 8]
Another great feature of extend()
is that we’re not restricted to lists; we can use any iterable. That includes tuples, strings, and generator expressions:
my_list = [] my_list.extend("Hello") # ['H', 'e', 'l', 'l', 'o'] my_list.clear() my_list.extend((1, 2, 3)) # [1, 2, 3] my_list.clear() my_list.extend(i for i in range(5)) # [0, 1, 2, 3, 4]
Of course, like append()
, extend()
doesn’t return anything. Instead, it modifies the existing list. Also like append()
, extend()
only adds the iterable to the end of the other list. There’s no way to specify where the input iterable goes. If you want more control, I suggest slice assignment or our next method, insert()
.
Add an Item to a List with Insert
If append()
and extend()
aren’t doing it for you, I recommend insert()
. It allows you to add an item to a list at any index:
my_list = [] my_list.insert(0, 5)
In this case, we inserted a 5 at index 0. Naturally, we can choose any valid index:
my_list = [2, 5, 7] my_list.insert(1, 6) # [2, 6, 5, 7]
And just like with regular list syntax, we can use negative indices:
my_list = [2, 5, 7] my_list.insert(-1, 9) # [2, 5, 9, 7]
How cool is that?! Unfortunately, however, we can’t really insert an entire list. Since Python lists don’t restrict type, we can add any item we want. As a result, inserting a list will literally insert that list:
my_list = [4, 5, 6] my_list.insert(1, [9, 10]) # [4, [9, 10], 5, 6]
Luckily, slice assignment can help us out here!
Performance
With all the solutions ready to go, let’s take a look at how they compare in terms of performance. Since each solution doesn’t do exactly the same thing, I’ll try to be fair in how I construct my examples. For instance, all the following examples will append a value at the end of each of the sample lists (ignoring the static assignment solutions):
setup = """ empty_list = [] small_list = [1, 2, 3, 4] large_list = [i for i in range(100000)] """ static_list_empty = "empty_list = []" static_list_small = "small_list = [1, 2, 3, 4, 5]" slice_assignment_empty = "empty_list[len(empty_list):] = [5]" slice_assignment_small = "small_list[len(small_list):] = [5]" slice_assignment_large = "large_list[len(large_list):] = [5]" append_empty = "empty_list.append(5)" append_small = "small_list.append(5)" append_large = "large_list.append(5)" extend_empty = "empty_list.extend([5])" extend_small = "small_list.extend([5])" extend_large = "large_list.extend([5])" insert_empty = "empty_list.insert(len(empty_list), 5)" insert_small = "small_list.insert(len(small_list), 5)" insert_large = "large_list.insert(len(large_list), 5)"
Now, let’s take a look at all the empty list examples:
>>> import timeit >>> min(timeit.repeat(setup=setup, stmt=static_list_empty)) 0.06050460000005842 >>> min(timeit.repeat(setup=setup, stmt=slice_assignment_empty)) 0.4962195999996766 >>> min(timeit.repeat(setup=setup, stmt=append_empty)) 0.17979939999986527 >>> min(timeit.repeat(setup=setup, stmt=extend_empty)) 0.27297509999971226 >>> min(timeit.repeat(setup=setup, stmt=insert_empty)) 0.49701270000059594
As expected, the most straightforward solution performs the best. Let’s see how that plays out as we grow our list:
>>> min(timeit.repeat(setup=setup, stmt=static_list_small)) 0.1380927000000156 >>> min(timeit.repeat(setup=setup, stmt=slice_assignment_small)) 0.5136848000001919 >>> min(timeit.repeat(setup=setup, stmt=append_small)) 0.1721136000005572 >>> min(timeit.repeat(setup=setup, stmt=extend_small)) 0.28814950000014505 >>> min(timeit.repeat(setup=setup, stmt=insert_small)) 0.5033762000002753
Again, append()
gets the job done the quickest. Now, let’s take a look at an enormous list:
>>> min(timeit.repeat(setup=setup, stmt=slice_assignment_large)) 0.5083946000004289 >>> min(timeit.repeat(setup=setup, stmt=append_large)) 0.18050170000060461 >>> min(timeit.repeat(setup=setup, stmt=extend_large)) 0.28858020000006945 >>> min(timeit.repeat(setup=setup, stmt=insert_large)) 0.5108225000003586
Amazingly, all these solutions seem to scale really well. That said, append()
takes the cake. After all, it is amortized O(1). In other words, appending to a list is a constant time operation as long as we don’t run out of space.
That said, take these performance metrics with a grain of salt. After all, not every solution is going to be perfect for your needs.
Challenge
Now that we know how to add an item to a list, let’s try writing a simple sorting algorithm. After all, that’s the perfect task for someone who wants to get familiar with the various list manipulation methods.
Personally, I don’t care which sorting algorithm you implement (e.g. bubble, insertion, merge, etc.) or what type of data you choose to sort (e.g. numbers, strings, etc.). In fact, I don’t even care if you sort the data in place or create an entirely separate list. All I care about is that you use one or more of the methods described in this article to get it done.
When you think you have a good solution, feel free to share it in the comments. As always, I’ll share an example in the comments.
A Little Recap
With all that out of the way, let’s take a look at all our solutions again:
# Statically defined list my_list = [2, 5, 6] # Appending using slice assignment my_list[len(my_list):] = [5] # [2, 5, 6, 5] # Appending using append() my_list.append(9) # [2, 5, 6, 5, 9] # Appending using extend() my_list.extend([-4]) # [2, 5, 6, 5, 9, -4] # Appending using insert() my_list.insert(len(my_list), 3) # [2, 5, 6, 5, 9, -4, 3]
By far, this has been one of my favorite articles to write in awhile. There’s nothing quite like learning something new while writing a short response to the question “How do I add an item to a list?”
If you liked this article, help me get it in front of more eyes by giving it a share. In addition, you can show your support by hopping on my mailing list, joining me on Patreon, or subscribing to my YouTube channel. Otherwise, check out some of these related articles:
- How to Print on the Same Line in Python
- How to Get the Last Item of a List in Python
- How I Display Code in My Python Videos (Patron-only)
Other than that, that’s all I’ve got! Thanks again for your support. See you next time!
Recent Posts
Teaching at the collegiate level is a wonderful experience, but it's not always clear what's involved or how you get there. As a result, I figured I'd take a moment today to dump all my knowledge for...
It's been a weird week. I'm at the end of my degree program, but it's hard to celebrate. Let's talk about it.