Using lists we organize and categorize ourselves and the environment around us. In Python lists are essentially a container of sequenced objects that are alike in nature. You are not restricted to having lists of only a single data type, however it is often not seen as very intuitive to use different types in a list.
Lists like strings are a sequence type which really means that we can use an index to access the data, we’ll have a look at slicing which is a feature of sequence types, allowing us to get portions of data instead of a singular item.
- Basic Manipulation
- Methods vs Functions
- List Methods
- Built-in Functions
- Slicing
- Multiple dimensions
- Reference Items
Basic Manipulation
Lists can be defined using box brackets []
and items are seperated by a comma
,
.
empty_list = []
numbers = [5, 12, 13, -1]
names = [
"Joe",
"Tom",
"Bob"
]
mixed = [1, "1", 2, "Joe"]
To get a specific item from the list, we can use an index value. Using an index value that does not exist will however throw an error.
print(names[0])
print(names[3])
> Joe
> IndexError: list index out of range
We can remove items from the list by using the del
operator.
del names[1]
print(names)
> ["Joe", "Bob"]
Even though both strings and lists are sequence types, a string is immutable
and the del
operator will throw an error.
word = "Hello"
del word[1]
> TypeError: <str> object does not support item deletion
We are going to need to be able to add to our list as well, we can do so using
the +
operator.
names = names + ["Peter", "Jane"]
print(names)
> ["Joe", "Bob", "Peter", "Jane"]
Methods vs Functions
Let’s quickly talk about the difference between methods and functions. Methods are part of an object and act on an object while functions are stand alone operations and take on arguments.
object.method() # this would be a method
function(object) # this would be a function
List Methods
List objects have several methods available we will cover some of the more common options.
We can add to our list using the append
method.
names.append("Sarah")
print(names)
> ["Joe", "Bob", "Peter", "Jane", "Sarah"]
The append
method only adds one item at a time, when we need to add a range
of items we can use the extend
method.
names.extend(["Lisa", "Zack"])
print(names)
> ["Joe", "Bob", "Peter", "Jane", "Sarah", "Lisa", "Zack"]
We can also remove from our list using the remove
method. The remove
method
will remove the first occurence of the item in the list.
names.remove("Peter")
print(names)
> ["Joe", "Bob", "Jane", "Sarah", "Lisa", "Zack"]
Say we want to sort our list of names, we can use the sort
method.
names.sort()
print(names)
> ["Bob", "Jane", "Joe", "Lisa", "Sarah", "Zack"]
We can add an item to a specific location using the insert
method.
names.insert(1, "Chloe")
print(names)
> ["Bob", "Chloe", "Jane", "Joe", "Lisa", "Sarah", "Zack"]
Built-in Functions
The min
function will return the smallest item in the list.
print(min(names))
> Bob
Similarly max
will return the largest item in the list.
print(max(names))
> Zack
The sum
function will return the items of the list added together, however it
is not valid for strings
numbers = [1,2,3]
print(sum(numbers))
print(sum(names))
> 6
> TypeError: unsupported operand type(s) for +: 'int' and 'str'
The len
function will return the number of items in the list. Unlike indexes
the len
function is not zero based.
print(len(names))
print(len(numbers))
> 7
> 3
Slicing
Slicing is really powerful once you are familiar with it. It allows you to modify your list in portions or slices.
The slicing syntax is as follows object[start:end:step]
. The step argument is
optional and we’ll talk about it a little later, for now let’s print our list
using slicing syntax.
print(names[:])
> ["Bob", "Chloe", "Jane", "Joe", "Lisa", "Sarah", "Zack"]
Now say that we want the last three names in the list? Let’s provide a start
position using the index value 4
print(names[4:])
> ["Lisa", "Sarah", "Zack"]
Say we want to get the first three names from our list? Let’s provide a end
position using the index value of 3
print(names[:3])
> ["Bob", "Chloe", "Jane"]
Say we want all the names except the first two names and last two names?
print(names[2:-2])
> ["Jane", "Joe", "Lisa"]
Notice how we used -2
as a position? This indicates that it is the index
value calculated from the end of the list. This concept can be used for all
the indexing operations we’ve looked at up until now, including indexing in
string objects.
It is important to know that the slicing start argument is inclusive and the
end argument is exclusive. What does this mean? Let’s try and get Jane
and
Joe
from the list.
print(names[2])
print(names[4])
print(names[2:4])
> Jane
> Lisa
> ["Jane", "Joe"]
Notice how Jane was included but Lisa was not. This is what is what is meant by inclusive and exclusive.
Now let’s try and get every second or third name in the list using the step argument.
print(names[::2])
print(names[::3])
> ["Bob", "Jane", "Lisa", "Zack"]
> ["Bob", "Joe", "Zack"]
We can provide a negative value for the step argument, which would also reverse the list.
print(names[::-1])
print(names[::-2])
> ['Zack', 'Sarah', 'Lisa', 'Joe', 'Jane', 'Chloe', 'Bob']
> ['Zack', 'Lisa', 'Jane', 'Bob']
We can do some interesting things though, for example we can replace a slice
with something completely new. Let’s replace Jane
and Joe
with a new list
of people.
names[2:4] = ["Theo", "Mandy", "Arnold", "Kim"]
print(names)
> ['Bob', 'Chloe', 'Theo', 'Mandy', 'Arnold', 'Kim', 'Lisa', 'Sarah', 'Zack']
Something to note is that the slice will return an entirely new list and not modify the existing list at all.
Multiple dimensions
We can create multiple dimension arrays as well, this really means that arrays are nested inside arrays. A common occurence of this is a 2d matrix.
array0 = [1, 2, 3]
array1 = [4, 5, 6]
array2 = [7, 8, 9]
arrays = [array0, array1, array2]
Accessing the items are much the same as before by providing an index.
print(arrays[1])
> [4, 5, 6]
And getting a specific nested item like 5
would look like this
print(arrays[1][1])
> 5
We can also modify items just like before with the newer syntax
arrays[1][1] = "MODIFIED"
print(array1)
print(arrays)
> [4, "MODIFIED", 6]
> [[1, 2, 3],[4, "MODIFIED", 6],[7, 8, 9]]
There is no limit to how many dimensions your array can have, however it is uncommon to go beyond two dimensions. It becomes extremely complicated to maintain a mental model of what is happening in your code.
Reference Items
Lists unlike strings are not immutable and use a reference that points to the original object. This means that we can change the original object and it would reflect in the list as well and visa versa.
Let’s say we have a list of chores.
chores = ["Takeout trash", "Feed animals", "Water plants"]
And we need to do these same chores every few days of the week.
# Mon Thu Sat
week = [chores, chores, chores]
You become environmentally aware and decide to recycle your trash.
chores[0] = "Recycle Trash"
print(week)
> [["Recycle Trash", "Feed animals", "Water plants"],
["Recycle Trash", "Feed animals", "Water plants"],
["Recycle Trash", "Feed animals", "Water plants"]]
Notice how the value changed in all the items in the array. That is because of the reference to the chores variable which we modified.
What if we wanted to only change a specific occurence? We will then want to change the way we create our week list.
A little earlier, I said that slicing returns an entirely new array, lets use that to create unique copies.
week = [chores[:], chores[:], chores[:]]
And now let’s do laundry on saturday instead of watering plants.
week[2][2] = "Laundry"
print(week)
> [["Recycle Trash", "Feed animals", "Water plants"],
["Recycle Trash", "Feed animals", "Water plants"],
["Recycle Trash", "Feed animals", "Laundry"]]
This brings us to the end of lists in python. Hope you enjoyed it! Don’t hesitate to get in contact with me on any of the platforms provided at the bottom of the page.