# Python3: Lists

January 24, 2019

Besides strings and numbers, Python has all sorts of different types of objects.

In this tutorial, you’ll learn about a very useful data structure in Python called lists — they are exactly what they sound like: they help you store lists of things. Let’s get started.

# Lists

Let’s go ahead and create a list:

print([])
# Output: []

Yes, this list is empty. Not very useful, right? Let’s create a list of lottery numbers. We don’t want to repeat ourselves all the time, so we will put it in a variable, too:

lottery = [3, 42, 12, 19, 30, 59]
print(lottery)
# Output: [3, 42, 12, 19, 30, 59]

# Finding number of elements in a list: len()

All right, we have a list! What can we do with it? Let’s see how many lottery numbers there are in the list. Do you have any idea which function you should use for that? You know this already!

lottery = [3, 42, 12, 19, 30, 59]
print(len(lottery))
# Output: 6

Yes! Just like a string, len() tells you the length of a list — which is just the number of items in the list. Handy, right?

# Sorting a list: sort()

Maybe we will sort it now:

lottery = [3, 42, 12, 19, 30, 59]
lottery.sort()
print(lottery)
# Output: [3, 12, 19, 30, 42, 59]

As you can see, the numbers in your list are now sorted from the lowest to highest value. Congrats!

Note: print(lottery.sort()) doesn’t do what you expect it to. lottery.sort() sorts the list, but it does not return anything. The list still gets sorted, but the output is None. What you need to do is, first sort the list using lottery.sort(), and then print the list using print(lottery) (as shown above).

# Reversing a list: reverse()

Maybe we want to reverse that order? Let’s do that!

lottery = [3, 12, 19, 30, 42, 59]
lottery.reverse()
print(lottery)
# Output: [59, 42, 30, 19, 12, 3]

Notice how similar the syntax is for sorting a list and for reversing it.

# Concatenating two lists: + operator

We can also concatenate two lists (just like strings):

print([1, 2] + [2, 3])
# Output: [1, 2, 2, 3]
lottery = [59, 42, 30, 19, 12, 3]
print(lottery + [37, 81, 56])
# Output: [59, 42, 30, 19, 12, 3, 37, 81, 56]

# Repeating a list: * operator

We can also repeat a list (again, just like strings):

print([1, 2]*4)
# Output: [1, 2, 1, 2, 1, 2, 1, 2]
lottery = [59, 42, 30, 19, 12, 3]
print(lottery*2)
# Output: [59, 42, 30, 19, 12, 3, 59, 42, 30, 19, 12, 3]

# Using indexes to access and modify elements

If you want to show only a single element, you can do this by using indexes. An index is the number that says where in a list an item occurs. Programmers prefer to start counting at 0, so the first object in your list is at index 0, the next one is at 1, and so on.

Try this:

lottery = [3, 42, 12, 19, 30, 59]
print(lottery[0])
# Output: 3
print(lottery[1])
# Output: 42

As you can see, you can access different objects in your list by using the list’s name and the object’s index inside of square brackets.

Accessing allows you to change the values as well.

lottery = [3, 42, 12, 19, 30, 59]
lottery[1] = 76
print(lottery)
# Output: [3, 76, 12, 19, 30, 59]
lottery[1] = 42
print(lottery)
# Output: [3, 42, 12, 19, 30, 59]

For extra fun, try some other indexes: 6, 7, 1000, -1, -6 or -1000. See if you can predict the result before trying the command. Do the results make sense?

# Appending a single element to a list

If you want to add a single element to your list, you can do this by using the append method:

lottery = [59, 42, 30, 19, 12, 3]
lottery.append(199)
print(lottery)
# Output: [59, 42, 30, 19, 12, 3, 199]

# Deleting elements from a list

To delete something from your list you will need to use indexes as we learned earlier and the pop() method. Let’s try an example and reinforce what we learned previously; we will be deleting the first number of our list.

lottery = [59, 42, 30, 19, 12, 3, 199]
print(lottery[0])
# Output: 59
lottery.pop(0)
print(lottery)
# Output: [42, 30, 19, 12, 3, 199]

That worked like a charm!

# Checking if an element exists in a list with in

Next, let’s look at how you can check if an element exists in a list. For this, we can use the in keyword.

lottery = [59, 42, 30, 19, 12, 3, 199]
if 42 in lottery:
print("42 is in lottery")  # Output: 42 is in lottery
print(41 in lottery)
# Output: False

That was simple enough! Next, let’s look at a common pattern of building lists.

# List build up

One common pattern is to start a list as the empty list [], then use append() to add elements to it:

characters_list = []          # Start as the empty list
characters_list.append('a')   # Use append() to add elements
characters_list.append('b')   # And so on..
print(characters_list)

Output:

['a', 'b']

# Using slices to access and modify sublists

Python also gives us a way to access any sublist of a list by using what are called slices. The way we access a slice of the list is by using [start_index:end_index+1] instead of just an index while accessing the list. Take a look at the example below:

characters_list = ['a', 'b', 'c', 'd']
print(characters_list[1:3])   ## Output: ['b', 'c']

Thus, in this example, we will print out the sublist from index 1 to index 2, i.e. the sublist ['b', 'c']. You may be wondering why we got everything till index 2, and not till index 3? This is because the second number in the slice specification 1:3 is not included. Slices start with the first element and include that, but stop at one before the last element.

In fact, you can even assign a single element to an entire slice, thereby changing sub-parts of the list.

characters_list = ['a', 'b', 'c', 'd']
characters_list[0:2] = 'z'     ## replace ['a', 'b'] with ['z']
print(characters_list)         ## ['z', 'c', 'd']

This is amazing! With just one statement, we were able to replace an entire sublist with a single element.

Another useful slicing technique to know is this:

characters_list = ['a', 'b', 'c', 'd']
print(characters_list[:])         ## ['a', 'b', 'c', 'd']

Thus, if we don’t specify a range [:], Python starts from 0 and returns the entire list. You may be wondering — what use will this ever be of? Let’s find out in the next section.

# Copying lists

Let’s try to copy lists the usual way we would copy any other variable:

lottery = [59, 42, 30, 19, 12, 3, 129]
lottery_copy = lottery
lottery_copy[1] = 41
print(lottery_copy)    # Output: [59, 41, 30, 19, 12, 3, 129]
print(lottery)         # Output: [59, 41, 30, 19, 12, 3, 129]

Look at the output of the last line — you’ll notice something strange. We didn’t even touch the original lottery list, but when we modified lottery_copy and updated the second element to 41 from 42, lottery also got modified. This is not something we want. For instance, when we copy two numbers, changing the copied number does not change the original number:

num = 42
num_copy = num
num_copy = 41
print(num_copy)    # Output: 41
print(num)         # Output: 42

So, what’s going on in the case of lists? Why is updating a copy updating the original as well? This is because, when we use the = operator to “copy” a list, Python doesn’t really create a new copy of our original list. Instead, it just creates another reference to the same block of memory that lottery referred to, and puts that reference in lottery_copy.

So, when we updated the 42 to 41 in lottery_copy, we inadvertently also updated the same for lottery:

The solution to our problem is simple. We just want to assign a copy of lottery, not the lottery itself. We just learnt a way to do that above in the section on slices!

lottery = [59, 42, 30, 19, 12, 3, 129]
lottery_copy = lottery[:]  # lottery[:] is a *copy* of all the elements
lottery_copy[1] = 41
print(lottery_copy)    # Output: [59, 41, 30, 19, 12, 3, 129]
print(lottery)         # Output: [59, 42, 30, 19, 12, 3, 129]

Yes, things are working great now! The change is on line 2 — we used the [:] slice to create a new copy of lottery and assigned that new copy (and not just a reference) to lottery_copy. Wonderful!

Note 1: References aren’t always a bad thing. Python uses references to save computation and make things more efficient. In general, when we do z = x, Python has to choose whether to create a copy, which is expensive, or to just create a reference, which is fast. For lists, Python uses references. If we are not going to modify z, a reference works just fine — and Python saved us computation. If we do need to modify, then we can explicitly ask Python to create a copy.

Note 2: Lists are the first object you learnt about that are mutable — that is, you can modify a list after creating it. Whenever you have mutable objects, be careful of whether you want another reference to the same object, or a copy.

# Summary

Awesome! In this tutorial, you learned about lists that are objects stored in a particular order. You learned to do a number of operations to the list:

• Finding number of elements with len()
• Sorting and reversing with sort() and reverse()
• Concatenating and repeating lists with the + and * operators
• Accessing and modifying elements using indexes[]
• Adding and deleting elements using append() and pop()
• Accessing and modifying sublists using slices[:]
• Copying lists properly

Excited for the next part?

Based on content from https://tutorial.djangogirls.org/en/python_introduction/