Intermediate Lists
Lists in Python are an in-built data helpful structure for storing data sequentially. Using lists to store data allows for both sequential and random data access by using an index.
Below are the following features of the Lists:
As illustrated in the above diagram, Lists are accessed using an index. One of the topics challenging to novices is understanding array indexing. Due to improper understanding of indexing, they tend to face many index exceptions or segmentation faults. Therefore, having sound knowledge of lists and how they are accessed using an index.
When accessing sequential data structures, the index determines the element's position with offset from the first element in programming.
Here is an illustration.
Remember, indexing of elements starts from 0 and not 1.
The 0'th element refers to the 1'st element. The 1'st element refers to the 2'dn element. The 2'nd index refers to the 3'rd element, and so no.
Think of it this way, whenever you access any element, think about the number of elements you must skip. Accordingly, if you're going to access the 0'th element or the very first element, think about how many elements you want to skip. In this case, it's zero(0), so the index will be zero(0). Likewise, if you're going to access the 4'th index (fifth element), you need to skip four(4) elements, so the index is going to be four(4).
Example:
Lists in Python are defined in two ways:
Example using the [] bracket:
Alternatively, we can also use the list() method to define a List. The list() method accepts an iterable type as an argument.
Example using the list() method:
['M', 'r', '.', ' ', 'A', 'n', 'd', 'e', 'r', 's', 'o', 'n'] <class 'list'>
Python allows for converting other iterable types to list and will be covered when those topics are touched upon.
You must use a comma(,) to separate list elements.
Below are some examples of lists.
As mentioned earlier, Lists are heterogenous, meaning they can store multiple data types, including other data structures.
2-Dimensional lists are lists that contain lists within themselves.
Example:
The first element(0'th) element of the lists is a list containing two elements.
You can access multi-dimensional lists using multiple indexes.
To access the element "A Nightmare on Lax Street 2: Ajax's Revenge", we would index as follows:
Let's break down the above statement.
By mentioning "movies_list" we are referring to the entirety of the list itself.
To access the first(0'th) element, we index it by writing [0].
By doing this, we would refer to:
Therefore, to access "A Nightmare on Lax Street 2: Ajax's Revenge" we would write the statement like the following:
This could also be interpreted as "Access the 1'st element of the 0'th element".
Exercise:
What would the statement be to print the value "Mission Is Not Possible - Rogue State (2015)"?
Give it a try and then click to reveal.Misc Fact: Images are stored as 2-Dimensional arrays.
Multi-Dimensional Lists are lists that store multiple lists within themselves. They are accessed by referring to their indexes. Below is an example of a 3-dimensional list.
Example
90
5000
6
Typically, most use cases are limited to using 3-Dimensional lists. However, there is no limitation to the dimensions one can define.
One of the things beginners find challenging to grasp is the handling of multi-dimensional lists. However, I'll make it easy for you to understand using the illustration below .
The above illustration depicts the memory model used by Python to store this multi-dimensional list. As you can observe, the three_d_lists stores three elements, each containing a list of two elements referring to another list.
In the above illustration, the index 0, 0 stores the reference to the List A.
The index 0, 1 stores the reference to the List B.
Index 2, 1 stores the reference to the List F.
All the above indexes merely stores the references to the list and not the list itself. Hence, making multi-dimensional lists possible.
3-Dimensional lists are elemental in 3-D modeling of objects, such as 3-D computer graphics.
In Python, you can use the in-built len() method to find out the length of the list.
Example:
There are 6 elements in the list.
We can access the last element in a list in two ways:
James Bond
James Bond
832
3.1456
Here, -1 refers to the last element, -2 refers to the second last, and -3 refers to the third from the last element.
In a lower-level programming language, checking the list for a value would be very inefficient. It would require traversing until the list is exhausted or the element is found. However, Python is a high-level language, and it provides an abstraction to handle such frequent tasks.
You might remember about the membership operators: in and not in. We can use them to check for the presence or absence of a value in a list.
True
True
The data structure "list" in Python is a mutable type. You are allowed to change the value of its elements by referring to the index and assigning it a new value.
Below is an example.
Before change: [8, 4, 2, 0, -1, 'Hello, World', 3.14, 'Jackson', 'alpha']
After change: [8, 4, 2, 0, -1, 'A new message', 3.14, 'Jackson', 'alpha']
Being a high-level language, Python provides a mechanism to access parts of a list without a performance penalty. It achieves it through slices.
Slices are references to parts of a list, meaning that they refer to an existing list when assigned and do not create a new list. Any changes made in a slice will reflect in the referred list as well.
Slices are created using the following syntax:
slice_name = list_name
Here is an example:
[100, 9, 1, 0, 3, 2, 111, 22, 3401, 403, 200, 2819]
As you can see, altering the 0th element of the slice changes the "my_list" list. It is because the 0'th element of the slice is the 1'st element of the list.
Python allows for creating a mutable list. Any change made will be independent of both lists.
Syntax:
new_list = original_list[start_index:end_index]
start_index and end_index are optional
Example:
[1, 2, 3, 4, 5]
[100, 2, 3, 4, 5]
You can even refer to a part of the list by using indexes.
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[100, 4, 5]
As mentioned earlier, elements in Lists are stored sequentially. However, Python allows for the inserting of elements at a specified index. To achieve that, Python provides the insert() method.
<list>.insert(<index>, <value to be inserted>)
Example:
Before insertion: [1, 2, 3]
After insertion: [100, 1, 2, 3]
The insert method will insert the given value at the specified index. It does not replace the value at the specified index.
Python allows for appending an element to the end of the list.
Syntax:
<list_name>.append(value_to_be_appeneded)
Below is an example:
[1, 2, 3, 4, 5, 6, 7]
Python allows for adding all the elements of a list into another list.
Syntax:
<list_name>.extend(<list>)
Example:
[1, 2, 3, 4, 5, 6, 7, 8]
As the example demonstrates, the extend method will append entire elements in the list "b" at the end of the list "a".
Alternatively, Python also allows for the two lists to be extended using the "+" operator. This operator is overloaded for performing the extension of the list.
Here is an example:
[1, 2, 3, 4, 5, 6, 7, 8]
Python allows for removing a value from the list. The remove() method will remove the first value from the beginning of the list. It will not remove all instances of the specified element, as the below example demonstrates.
Example:
my_list before: [89, 392, 9900, 1, 2, 3, 4, 5, 6, 201, 1]
my_list after: [89, 392, 9900, 2, 3, 4, 5, 6, 201, 1]
Removing an item specified by the value.
This method is useful when the index of the value to be removed is unknown.
If the index of the value to be removed is known, use the pop() method to remove it.
Example:
Before pop(): [18, 393, 299, 19111, 'Hello, World']
After pop(): [18, 393, 299, 19111]
The above example removes the element "Hello, World" at the index of 4.
Alternatively, Python also provides the del keyword to delete a value.
Before del: [100, 1109333293, 301, 188409]
After del: [100, 301, 188409]
The clear() method deletes the entire elements in the list.
Before clear(): [303, 39222, 19, 0.12, 3.14]
After clear(): []
Doing this is essentially the same as assigning an empty list, as demonstrated below.
Before: [10, 100, 1000, 10000, 1001000]
After : []
Lists in Python are sequential data structures and are linearly accessed.
Python provides two looping mechanisms discussed earlier:
Example
# Traversing using for loop
for <identifier> in <list>:
# statement 1
# statement 2
...
...
# statement N
Example:
1
A
B
C
2
3
D
4
Alternatively, you can also traverse the list by indexing the list, as demonstrated in the example below.
8
3
0
1
-1
348
3.14
Hello, World
Let's break down each statement in the above example.
The statement
The second statement
The statement for
In this example, the range method takes a single value specifying the length of the list and returns an iterator for the loop to iterate through.
The last statement prints the value of the list specified by the index.
Python provides the use of the while statement to iterator through a loop. Here is an example:
8
3
0
1
-1
348
3.14
Hello, World
According to best programming practices, one should avoid using the while statement, as it makes the code unclear and opens opportunities for bugs to appear.
Suppose you might want to create a new list based on specific criteria. For example, let's write a program to create a list with even numbers.
[4, 0, 2, 26, 28, 98]
Writing the program, as shown above, is correct and will generate the correct output. However, it's too verbose. Thankfully, Python provides a shorter syntax to achieve the same result.
[4, 0, 2, 26, 28, 98]
Now, let's break down the second statement as follows.
The Right-Hand side expression is read as follows:
Insert the value "x" for every value in "old_list" if the remainder of x equals zero when divided by two.
Python provides the in-built sort() method to sort the list in either ascending or descending order.
To sort the list in ascending order refer the following example:
My List before sorting(): [5, 4, 3, 2, 1]
My List after sorting(): [1, 2, 3, 4, 5]
To sort the list in descending order refer the following example:
The statement
Remember to sort the list in descending order, use the "reverse=True" as an argument to the sort() method.
During data handling, there could be scenarios where the list needs to be processed in reverse order. To achieve that, Python provides the reverse() method.
Example:
Before reverse(): [11, 22, 33, 44]
After reverse(): [44, 33, 22, 11]
Since Python is an object-oriented language, everything in Python is an object; this includes variables, lists, tuples, dictionaries.
However, some types are reference-based, like lists, and some are value-based, like int types.
Due to this, you cannot copy a list just by using the "=" operator. Doing so will not create another list but will refer to the same list.
Hence, as a result, any changes made in the reference will reflect in the original list.
[8, 2, 3]
[8, 2, 3]
True
True
As the example above demonstrates, assigning the list will create a reference known as a shallow copy and not a separate object.
To create a deep copy, Python provides the copy() method.
[1, 2, 3]
[8, 2, 3]
False
False
In this chapter, we learned about the in-built data structure lists, their structure, accessing elements in a list, defining lists, creating lists using multiple techniques, accessing multi-dimensional lists and their uses, counting the elements in a list, and various approaches to access the last element.
Additionally, checking for an element in a list using the in and not in operator, modifying them, reference types, a.k.a a slice, creating a mutable copy, and going through several in-built methods for manipulating lists, deleting elements using the del statement.