Python's .append(): Add Items to Your Lists in Place

Python's .append(): Add Items to Your Lists in Place

by Leodanis Pozo Ramos Jan 04, 2021 basics python

Adding items to a list is a fairly common task in Python, so the language provides a bunch of methods and operators that can help you out with this operation. One of those methods is .append(). With .append(), you can add items to the end of an existing list object. You can also use .append() in a for loop to populate lists programmatically.

In this tutorial, you’ll learn how to:

  • Work with .append()
  • Populate lists using .append() and a for loop
  • Replace .append() with list comprehensions
  • Work with .append() in array.array() and collections.deque()

You’ll also code some examples of how to use .append() in practice. With this knowledge, you’ll be able to effectively use .append() in your programs.

Adding Items to a List With Python’s .append()

Python’s .append() takes an object as an argument and adds it to the end of an existing list, right after its last element:

>>>
>>> numbers = [1, 2, 3]
>>> numbers.append(4)
>>> numbers
[1, 2, 3, 4]

Every time you call .append() on an existing list, the method adds a new item to the end, or right side, of the list. The following diagram illustrates the process:

Python's .append()

Python lists reserve extra space for new items at the end of the list. A call to .append() will place new items in the available space.

In practice, you can use .append() to add any kind of object to a given list:

>>>
>>> mixed = [1, 2]

>>> mixed.append(3)
>>> mixed
[1, 2, 3]

>>> mixed.append("four")
>>> mixed
[1, 2, 3, 'four']

>>> mixed.append(5.0)
>>> mixed
[1, 2, 3, 'four', 5.0]

Lists are sequences that can hold different data types and Python objects, so you can use .append() to add any object to a given list. In this example, you first add an integer number, then a string, and finally a floating-point number. However, you can also add another list, a dictionary, a tuple, a user-defined object, and so on.

Using .append() is equivalent to the following operation:

>>>
>>> numbers = [1, 2, 3]

>>> # Equivalent to numbers.append(4)
>>> numbers[len(numbers):] = [4]
>>> numbers
[1, 2, 3, 4]

In the highlighted line, you perform two operations at the same time:

  1. You take a slice from numbers using the expression numbers[len(numbers):].
  2. You assign an iterable to that slice.

The slicing operation takes the space after the last item in numbers. Meanwhile, the assignment operation unpacks the items in the list to the right of the assignment operator and adds them to numbers. However, there’s an important difference between using this kind of assignment and using .append(). With the assignment, you can add several items to the end of your list at once:

>>>
>>> numbers = [1, 2, 3]

>>> numbers[len(numbers):] = [4, 5, 6]
>>> numbers
[1, 2, 3, 4, 5, 6]

In this example, the highlighted line takes a slice from the end of numbers, unpacks the items in the list on the right side, and adds them to the slice as individual items.

.append() Adds a Single Item

With .append(), you can add a number, list, tuple, dictionary, user-defined object, or any other object to an existing list. However, you need to keep in mind that .append() adds only a single item or object at a time:

>>>
>>> x = [1, 2, 3, 4]
>>> y = (5, 6)

>>> x.append(y)
>>> x
[1, 2, 3, 4, (5, 6)]

What happens here is that .append() adds the tuple object y to the end of your target list, x. What if you want to add each item in y to the end of x as an individual item and get [1, 2, 3, 4, 5, 6]? In that case, you can use .extend():

>>>
>>> x = [1, 2, 3, 4]
>>> y = (5, 6, 7)
>>> x.extend(y)
>>> x
[1, 2, 3, 4, 5, 6, 7]

>>> x = [1, 2, 3, 4]
>>> y = (5, 6, 7)
>>> # Equivalent to x.extend(y)
>>> x[len(x):] = y
>>> x
[1, 2, 3, 4, 5, 6, 7]

.extend() takes an iterable as an argument, unpacks its items, and adds them to the end of your target list. This operation is equivalent to x[len(x):] = y, which is the same technique you saw in the previous section.

.append() Returns None

In practice, .append() does its work in place by modifying and growing the underlying list. This means that .append() doesn’t return a new list with an additional new item at the end. It returns None:

>>>
>>> x = [1, 2, 3, 4]
>>> y = x.append(5)
>>> y is None
True
>>> x
[1, 2, 3, 4, 5]

Like with several similar methods, .append() changes the underlying list in place. Trying to use the return value of .append() is a common mistake when it comes to learning how mutable sequence types work. Keeping this behavior of .append() in mind will help you prevent errors in your code.

Populating a List From Scratch

A common problem that you might face when working with lists in Python is how to populate them with several items for further processing. There are two ways to do this:

  1. Use .append() and a for loop
  2. Use a list comprehension

In the next few sections, you’ll learn how and when to use these techniques to create and populate Python lists from scratch.

Using .append()

One common use case of .append() is to completely populate an empty list using a for loop. Inside the loop, you can manipulate the data and use .append() to add successive results to the list. Say you need to create a function that takes a sequence of numbers and returns a list containing the square root of each number:

>>>
>>> import math

>>> def square_root(numbers):
...     result = []
...     for number in numbers:
...         result.append(math.sqrt(number))
...     return result
...

>>> numbers = [1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> square_root(numbers)
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]

Here, you define square_root(), which takes a list of numbers as an argument. Inside square_root(), you create an empty list called result and start a for loop that iterates over the items in numbers. In each iteration, you use math.sqrt() to calculate the square root of the current number and then use .append() to add the result to result. Once the loop finishes, you return the resulting list.

This way of populating lists is fairly common in Python. However, the language provides some convenient constructs that can make the process a lot more efficient and Pythonic. One of these constructs is a list comprehension, which you’ll see in action in the next section.

Using a List Comprehension

In practice, you often replace .append() with a list comprehension when creating a list from scratch and populating it. With a list comprehension, you can reimplement square_root() like this:

>>>
>>> import math

>>> def square_root(numbers):
...     return [math.sqrt(number) for number in numbers]
...

>>> numbers = [1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> square_root(numbers)
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]

The list comprehension inside square_root() creates a list containing the square root of number for each number in numbers. This reads almost like plain English. Also, this new implementation will be more efficient in terms of processing time than the implementation that uses .append() along with a for loop.

To turn .append() into a list comprehension, you just need to put its argument followed by the loop header (without the colon) inside a pair of square brackets.

Switching Back to .append()

Even though list comprehensions can be more readable and efficient than .append() for populating lists, there might be situations where .append() is a better choice.

Suppose you need square_root() to provide your users with detailed information about the progress of calculating the square root of the input list of numbers. To report the operation progress, you can use print():

>>>
>>> import math

>>> def square_root(numbers):
...     result = []
...     n = len(numbers)
...     for i, number in enumerate(numbers):
...         print(f"Processing number: {number}")
...         result.append(math.sqrt(number))
...         print(f"Completed: {int((i + 1) / n * 100)}%")
...     return result
...

>>> numbers = [1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> square_root(numbers)
Processing number: 1
Completed: 11%
...
Processing number: 81
Completed: 100%
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]

Now think of how you can turn the body of square_root() into a list comprehension. Using print() inside a list comprehension doesn’t seem coherent or even possible unless you wrap part of the code in a helper function. So, in this example, using .append() is the right choice.

The moral behind the above example is that there are some situations in which you can’t replace .append() with a list comprehension or with any other construct.

Creating Stacks and Queues With Python’s .append()

So far, you’ve learned how to use .append() to add a single item to a list or to populate lists from scratch. Now it’s time for a different and more specific kind of example. In this section, you’ll learn how to use a Python list to create stack and queue data structures with the minimal required functionality using .append() and .pop().

Implementing a Stack

A stack is a data structure that stores items on top of each other. Items come in and out of the stack in a Last-In/First-Out (LIFO) fashion. Typically, a stack implements two main operations:

  1. push adds an item to the top, or end, of the stack.
  2. pop removes and returns the item at the top of the stack.

In a list, .append() is equivalent to a push operation, so you can use it to push items onto the stack. Lists also provide .pop(), which optionally takes an integer index as an argument. It returns the item at that index in the underlying list and also removes the item:

>>>
>>> numbers = [1, 2, 3]
>>> numbers.pop(1)
2
>>> numbers
[1, 3]

>>> numbers.pop()
3
>>> numbers
[1]

>>> numbers.pop()
1
>>> numbers
[]

>>> numbers.pop()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    numbers.pop()
IndexError: pop from empty list

If you supply an integer index as an argument to .pop(), then the method returns and removes the item at that index in the list. Calling .pop() without an argument returns the last item in the list. Note that .pop() also removes the item from the underlying list. Finally, if you call .pop() on an empty list, then you’ll get an IndexError.

With this knowledge, you’re ready to implement a stack using .append() and .pop(). Here’s a class that defines a stack. The class provides .push() and .pop() operations:

class Stack:
    def __init__(self):
        self._items = []

    def push(self, item):
        self._items.append(item)

    def pop(self):
        try:
            return self._items.pop()
        except IndexError:
            print("Empty stack")

    def __len__(self):
        return len(self._items)

    def __repr__(self):
        return f"Stack({self._items})"

In Stack, you first initialize the instance attribute ._items. This attribute holds an empty list that you’ll use to store the items in the stack. Then you code .push(), which implements the push operation using .append() on ._items.

You also implement the pop operation by calling .pop() on the underlying list, ._items. In this case, you use a try and except block to handle the IndexError that occurs when you call .pop() on an empty list.

The special method .__len__() provides the required functionality for retrieving the length of the internal list ._items. The special method .__repr__() allows you to provide a user-friendly string representation of the stack when printing the data structure to the screen.

Here are some examples of how you can use Stack in practice:

>>>
>>> stack = Stack()

>>> # Push items onto the top of the stack
>>> stack.push(1)
>>> stack.push(2)

>>> # User-friendly printing format
>>> stack
Stack([1, 2])
>>> print(stack)
Stack([1, 2])

>>> # Retrieve the length of the stack
>>> len(stack)
2

>>> # Pop items from the top of the stack
>>> stack.pop()
2
>>> stack.pop()
1
>>> stack.pop()
Empty stack
>>> stack
Stack([])

That’s it! You’ve coded a stack data structure that implements the push and pop operations. It also provides functionality to get the length of the underlying list and to print the entire stack in a user-friendly manner.

Implementing a Queue

Queues are data structures that commonly manage their items in a First-In/First-Out (FIFO) fashion. Queues work like a pipe in which you push in new items at one end, and old items pop out from the other end.

Adding an item to the end of a queue is known as an enqueue operation, and removing an item from the front, or beginning, of a queue is known as a dequeue operation.

You can enqueue items using .append() and dequeue them using .pop(). This time, you need to provide 0 as an argument to .pop() just to make it retrieve the first item in the list instead of the last item. Here’s a class that implements a queue data structure using a list to store its items:

class Queue:
    def __init__(self):
        self._items = []

    def enqueue(self, item):
        self._items.append(item)

    def dequeue(self):
        try:
            return self._items.pop(0)
        except IndexError:
            print("Empty queue")

    def __len__(self):
        return len(self._items)

    def __repr__(self):
        return f"Queue({self._items})"

This class is quite similar to your Stack. The main difference is that .pop() takes 0 as an argument to return and removes the first item in the underlying list, ._items, rather than the last.

The rest of the implementation is almost identical but uses appropriate names, such as .enqueue() for adding items and .dequeue() for removing them. You can use Queue the same way you used Stack in the above section: just call .enqueue() to add items and .dequeue() to retrieve and remove them.

Using .append() in Other Data Structures

Other Python data structures also implement .append(). The operating principle is the same as the traditional .append() in a list. The method adds a single item to the end of the underlying data structure. However, there are some subtle differences.

In the next two sections, you’ll learn how .append() works in other data structures, such as array.array() and collections.deque().

array.append()

Python’s array.array() provides a sequence-like data structure that can compactly represent an array of values. These values must be of the same data type, which is limited to C-style data types, such as characters, integer numbers, and floating-point numbers.

array.array() takes the following two arguments:

Argument Content Required
typecode A single-character code that identifies the data type that the array can store Yes
initializer A list, bytes-like object, or iterable that serves as an initializer No

The documentation of array provides complete information about all the allowed type codes that you can use when creating arrays. The following example uses the "i" type code to create an array of integer numbers:

>>>
>>> from array import array

>>> # Array of integer numbers
>>> int_array = array("i", [1, 2, 3])
>>> int_array
array('i', [1, 2, 3])
>>> int_array[0]
1
>>> int_array[:2]
array('i', [1, 2])
>>> int_array[2] = 4
>>> int_array
array('i', [1, 2, 4])

To create an array, you need to provide a single-character code to define the data type of the values in the array. You can also provide an optional list of values with the appropriate type to initialize the array.

Arrays support most list operations, such as slicing and indexing. Like lists, array.array() also provides a method called .append(). This method works similarly to its list counterpart, adding a single value to the end of the underlying array. However, the value must have a data type that’s compatible with the existing values in the array. Otherwise, you’ll get a TypeError.

For example, if you have an array with integer numbers, then you can’t use .append() to add a floating-point number to that array:

>>>
>>> from array import array

>>> a = array("i", [1, 2, 3])
>>> a
array('i', [1, 2, 3])

>>> # Add a floating-point number
>>> a.append(1.5)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    a.append(1.5)
TypeError: integer argument expected, got float

If you try to add a floating-point number to a, then .append() fails with a TypeError. That’s because Python can’t automatically convert a floating-point number into an integer number without losing information.

In contrast, if you have an array with floating-point numbers and try to add integer numbers to it, then your operation will succeed:

>>>
>>> from array import array

>>> float_array = array("f", [1.0, 2.0, 3.0])
>>> float_array
array('f', [1.0, 2.0, 3.0])

>>> # Add and integer number
>>> float_array.append(4)
>>> float_array
array('f', [1.0, 2.0, 3.0, 4.0])

Here, you use .append() to add an integer number to an array of floating-point numbers. That’s possible because Python can automatically convert integer numbers into floating-point numbers without losing information in the process.

deque.append() and deque.appendleft()

collections.deque() is another data structure that implements a variation of .append(). A deque is a generalization of a stack and a queue specially designed to support fast and memory-efficient append and pop operations on both of its sides. So if you need to create a data structure with these features, then consider using a deque instead of a list.

collections.deque() takes the following two optional arguments:

Argument Content
iterable An iterable that serves as an initializer
maxlen An integer number that specifies the maximum length of the deque

If you provide a value to maxlen, then your deque will only store up to maxlen items. Once the deque is full, adding a new item will automatically cause the item at the opposite end of the deque to be discarded. On the other hand, if you don’t supply a value to maxlen, then the deque can grow to an arbitrary number of items.

In deques, .append() also adds a single item to the end, or right side, of the underlying data structure:

>>>
>>> from collections import deque

>>> d = deque([1, "a", 3.0])
>>> d
deque([1, 'a', 3.0])

>>> d.append("b")
>>> d
deque([1, 'a', 3.0, 'b'])

Like lists, deques can hold different types of items, so .append() adds arbitrary items to the end of the deque. In other words, with .append(), you can add any object to a deque.

Besides .append(), deques also provide .appendleft(), which adds a single item to the beginning, or left side, of a deque. Similarly, deques provide .pop() and .popleft() to remove items from the right and left side of the deque, respectively:

>>>
>>> from collections import deque

>>> d = deque([1, "a", 3.0])
>>> d.appendleft(-1.0)
>>> d
deque([-1.0, 1, 'a', 3.0])

>>> d.pop()
3.0

>>> d.popleft()
-1.0

>>> d
deque([1, 'a'])

The call to .appendleft() adds -1.0 to the left side of d. On the other hand, .pop() returns and removes the last item in d, and .popleft() returns and removes the first item. As an exercise, you can try to implement your own stack or queue using a deque instead of a list. To do this, you can take advantage of the examples you saw in the section Creating Stacks and Queues With Python’s .append().

Conclusion

Python provides a method called .append() that you can use to add items to the end of a given list. This method is widely used either to add a single item to the end of a list or to populate a list using a for loop. Learning how to use .append() will help you process lists in your programs.

In this tutorial, you learned:

  • How .append() works
  • How to populate lists using .append() along with a for loop
  • When to replace .append() with a list comprehension
  • How .append() works in array.array() and collections.deque()

In addition, you coded some examples of how to use .append() to create data structures, such as stacks and queues. This knowledge will allow you to use .append() to grow your lists efficiently and effectively.

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Leodanis Pozo Ramos

Leodanis Pozo Ramos Leodanis Pozo Ramos

Leodanis is an industrial engineer who loves Python and software development. He is a self-taught Python programmer with 5+ years of experience building desktop applications.

» More about Leodanis

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to hundreds of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python Skills
With Unlimited Access to Real Python

Join us and get access to hundreds of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Real Python Comment Policy: The most useful comments are those written with the goal of learning from or helping out other readers—after reading the whole article and all the earlier comments. Complaints and insults generally won’t make the cut here.

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Keep Learning

Related Tutorial Categories: basics python