What Does [:] Mean In Python? Code Examples

When using the slice operator [start:stop:step] to capture only a subset of data from an original list or string, what does [:] do?

The slice operator containing no values for the start and stop positions returns a complete copy of the original string or list. This is helpful when you want to perform a shallow copy of your list.

Besides using the built-in list method .copy() you can use this shortcut slice operator (a whole 4 characters less) in its place.

Let’s look at an example:

>>> a_list = [1, 2, 3]
>>> b_list = a_list
>>> a_list[0] = 100
>>> print(b_list)
[100, 2, 3]

The initial thought for those fresh to coding would be: I thought I was just copying the a_list to a new variable b_list before a_list was modified, why did b_list change too?

This has to do with how variables are stored in memory. A way to demonstrate this is by looking at the built-in function id() and the reserved operator is .

>>> a_list = [1, 2, 3]
>>> b_list = a_list
>>> id(a_list)
4670898112
>>> id(b_list)
4670898112
>>> a_list is b_list
True

From the example above you can see that the built-in id() function returns a reference number to each variable and the id number for both variables is the same.

This means that the two variables are pointing to the same object in memory and are equivalent. The operator is performs this test on equivalency and returns True because both variables point to the same object reference.

Therefore the point being made is that because each variable points to the same object if you modify the object through either variable it will mean the other variable changes too.

>>> a_list = [1, 2, 3]
>>> b_list = a_list
>>> a_list[0] = 10
>>> b_list[1] = 20
>>> print(a_list)
[10, 20, 3]
>>> print(b_list)
[10, 20, 3]
>>> id(a_list)
4369259008
>>> id(b_list)
4369259008

As you can see both variables return the same result because they both point to the same object.

But what if you don’t want this? What if you want to capture a copy of a_list before it changes?

How To Make A Shallow Copy Of A List

One way to do this is to create a shallow copy of your list using the [:] slice operator.

Let’s look at our previous example again, but this time will use the slice operator at the opportune moment:

>>> a_list = [1, 2, 3]
>>> b_list = a_list[:]
>>> a_list[0] = 100
>>> print(a_list)
[100, 2, 3]
>>> print(b_list)
[1, 2, 3]
>>> id(a_list)
4369256192
>>> id(b_list)
4369259008
>>> a_list is b_list
False

Notice the difference here?

In the code example above the a_list is created and the b_list is created as a copy of a_list before any changes are made to the original a_list list. Then when a change is made to a_list it does not change b_list and we can check that these are different by inspecting their object id references, which are both different.

What Is A “Shallow Copy”?

A shallow copy performs a copy of the original list, but keeps the same id references from the original list. If you were to inspect the id of each object in the list they would return their unique id:

>>> a_list = [{'a': 1}, 2]
>>> id(a_list[0])
4368574528
>>> id(a_list[1])
4365461840
>>> id(a_list)
4369259008

As you can see the list has a unique id and each element within the list has its own unique id. When you make a shallow copy of this list using the slice operator [:] you are keeping all the same references of the original:

>>> b_list = a_list[:]
>>> id(b_list[0])
4368574528
>>> id(b_list[1])
4365461840
>>> id(b_list)
4365778496
>>> a_list is b_list
False

The only difference above with the original a_list example is that the id reference of b_list is different. Even though both lists contain the exact same references and values the equivalency test returns False because the variable id references are not the same.

If you look at the dictionary which was inserted into the first element of the a_list what would happen if this changed?

>>> a_list[0]['a'] = 100
>>> print(b_list[0])
{'a': 100}
>>> a_list[1] = 200
>>> print(b_list[1])
2

Notice how by changing the dictionary of the first element it changed the first element in the b_list , whereas when the second element was reassigned to a new value it did not change the second element in the b_list .

This is why we call the shortcut copy method [:] a shallow copy . There are some elements, such as a dictionary, which if changed in the original list will modify the elements in the copied list because a shallow copy creates a new variable, but retains the same reference ids of the original list.

Summary

A shortcut way to copy a list or a string is to use the slice operator [:] . This will make a shallow copy of the original list keeping all object references the same in the copied list. This may work well for lists that are completely reassigned new values but would not work well if elements within the original list are modified and these elements are dictionaries.

The built-in list method .copy() performs the exact same task as the empty slice operator [:] but the slice operator does so with less characters, hence why it’s deemed to be a shortcut approach to copying.

Ryan Sheehy

Author of scripteverything.com, Ryan has been dabbling in code since the late '90s when he cut his teeth by exploring VBA in Excel when trying to do something more. Having his eyes opened with the potential of automating repetitive tasks, he expanded to Python and then moved over to scripting languages such as HTML, CSS, Javascript and PHP. When he is not behind a screen, Ryan enjoys a good bush walk with the family during the cooler months, and going with them to the beach during the warmer months.

Recent Posts