Home
About Us Privacy Policy
 

LISTS IN PYTHON

ADVERTISEMENT

Intermediate Lists



What are Lists, and Why are they used?

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:

  1. They are mutable data structures, i.e., they allow for altering of values.
  2. They allow for storing values of heterogeneous data types, i.e., storing values of any data type and data structures, including all in-built data structures.
  3. They allow for storing duplicate values.
  4. Lists can be used to implement data structures such as Stacks and Queues.
  5. They allow for random data access.
The Data stored in a list is also referred to as elements.


Structure of Lists



How are they accessed?

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.


number = [-11, 22, 3, -44, 5, 6, -77, 8, 9]

In the above list:

number[2]
is referring to the value 3.
number[0]
is referring to the value -11.
number[7]
is referring to the value 8.

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:

numbers = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

# To access the value at an index of 4
# I need to skip four elements
fourth_element = numbers[4]   # 5 is the value at this index


How are lists defined in Python?

Lists in Python are defined in two ways:

  1. Using the square brackets: []
  2. Using the list() method

Example using the [] bracket:

a_list_of_first_six_even_numbers = [0, 2, 4, 6, 8, 10]

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:

my_name = "Mr. Anderson"

# Convert string into a list with individual letters as elements.
characters_in_my_name = list(my_name)

print(characters_in_my_name, type(characters_in_my_name))

['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.

l1 = [ 1, 2, "James Bond", 3.14159265358979323846264, -101]
movies_list = [ 
    "Girl is Gone",
    "Alone in Home",
    "Mission Is Not Possible"
]
my_friends_name = ["Ajax", "Richard", "Darwin"]


2-Dimensional List

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:

movies_list = [ 
    [
        "A Nightmare on Lax Street",
        "A Nightmare on Lax Street 2: Ajax's Revenge",
    ],
    "Girl is Gone",
    "Alone in Home",
    [
        "Mission Is Not Possible (1996)",
        "Mission Is Not Possible 2 (2000)",
        "Mission Is Not Possible III (2006)",
        "Mission Is Not Possible - Phantom Protocol (2011)",
        "Mission Is Not Possible - Rogue State (2015)",
        "Mission Is Not Possible (2018)",
        "Mission Is Not Possible 7 (2022)",
    ]
]

The first element(0'th) element of the lists is a list containing two elements.

Accessing 2-Dimensional lists

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:

print(movies_list [0][1])

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:

[
    "A Nightmare on Lax Street",
    "A Nightmare on Lax Street 2: Ajax's Revenge",
]

Therefore, to access "A Nightmare on Lax Street 2: Ajax's Revenge" we would write the statement like the following:

print(movies_list [0][1])

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.

print(movies_list[3][4])

Misc Fact: Images are stored as 2-Dimensional arrays.


ADVERTISEMENT

Multi-Dimensional Lists

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

three_d_list = [
    [                              # 0
        [1, 2, 3, 4,  5],  # A # 0
        [6, 7, 8, 9, 10]   # B # 0
    ],                             # 0
    [                                     # 1
        [10, 20, 30, 40,  50],    # C # 1
        [60, 70, 80, 90, 100]     # D # 1
    ],                                    # 1
    [                                             # 2
        [1000, 2000, 3000, 4000,  5000],    # E # 2
        [6000, 7000, 8000, 9000, 10000]     # F # 2
    ]                                             # 2
]

print(three_d_list[1][1][3])   # 90
print(three_d_list[2][0][4])   # 5000
print(three_d_list[0][1][0])   # 6

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 .


Fig. Multi-Dimensional A


Fig. Multi-Dimensional B

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.


Finding the count of elements in a List?

In Python, you can use the in-built len() method to find out the length of the list.

Example:

my_fav_list = [198, 392, 0.65, 3.1456, 832, "James Bond"]
list_len = len(my_fav_list)
print(f"There are {list_len} elements in the list.")

There are 6 elements in the list.


Accessing the last element

We can access the last element in a list in two ways:

  1. Find the length of the list and then use an index
  2. Using negative indexes

Method #1: Using the length of the list and then use an index

# Accessing the last element by finding list length
my_fav_list = [198, 392, 0.65, 3.1456, 832, "James Bond"]
list_len = len(my_fav_list)
last_element_index = list_len - 1
print(my_fav_list[last_element_index])

James Bond

Method #2: Using negative indexes

# Using negative indexes to access elements from the end
my_fav_list = [198, 392, 0.65, 3.1456, 832, "James Bond"]
index = -1
print(my_fav_list[index])    # "James Bond"

index = -2
print(my_fav_list[index])   # 832

index = -3
print(my_fav_list[index])    # 3.1456

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.


Checking the existence of a particular value

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.

# To check the list for the presence of a value
my_list = [90, 5, 'Hello, World', [1, 2, 3, 4], 3.14, 786]
PI = 3.14
is_present = PI in my_list
print("Is PI present? ", is_present)

# Speed of light in m/s
speed_of_light = 299792458
is_present = speed_of_light not in my_list
print("Is Speed of Light present? ", is_present)

True
True


Changing the element in a list

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.

# Changing an element
my_list = [8,  4, 2, 0, -1, "Hello, World", 3.14, "Jackson", "alpha"]

print("Before change: ", my_list)

# Changing the 6'th element
my_list[5] = "A new message"

print("After change: ", my_list)

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']


ADVERTISEMENT

Slicing in Lists and Reference Types

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:

my_list = [8, 9, 1, 0, 3, 2, 111, 22, 3401, 403, 200, 2819]

# The slice "s" actually refers to the "my_list".
# Any changes made to s will reflect in my_list as well.
s = my_list

# Change the value of the 0th element of the slice
s [0] = 100

print(my_list)

[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.


Creating a mutable copy

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:

# Example
my_list = [1, 2, 3, 4, 5]
c = my_list[:]
c[0] = 100
print(my_list)
print(c)

[1, 2, 3, 4, 5]
[100, 2, 3, 4, 5]

You can even refer to a part of the list by using indexes.

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
c = my_list[2:5]   # Create a copy
c[0] = 100
print(my_list)
print(c)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[100, 4, 5]

Inserting a new item

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.

The insert() method takes two arguments or values.

<list>.insert(<index>, <value to be inserted>)

Example:

my_list = [ 1, 2, 3]

print("Before insertion: ", my_list)
my_list.insert(0, 100)
print("After insertion: ", my_list)

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.


Adding an element to the end of the list

Python allows for appending an element to the end of the list.

Syntax:

<list_name>.append(value_to_be_appeneded)

The append() method accepts one value.

Below is an example:

my_list = [1, 2, 3, 4]
my_list.append(5)
my_list.append(6)
my_list.append(7)
print(my_list)

[1, 2, 3, 4, 5, 6, 7]


Extending Lists in Python

Python allows for adding all the elements of a list into another list.

Syntax:

<list_name>.extend(<list>)

Example:

a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
a.extend(b)
print(a)

[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:

a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
c = a + b
print(c)

[1, 2, 3, 4, 5, 6, 7, 8]


Removing an item specified by the value.

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 = [89, 392, 9900, 1, 2, 3, 4, 5, 6, 201, 1]
print("my_list before: ", my_list)
my_list.remove(1)
print("my_list after: ", my_list)

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.


Remove an element specified by its index.

If the index of the value to be removed is known, use the pop() method to remove it.

Example:

my_list = [18, 393, 299, 19111, "Hello, World"]
print("Before pop(): ", my_list)
my_list.pop(4)
print("After pop(): ", my_list)

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.


The del statement

Alternatively, Python also provides the del keyword to delete a value.

my_list = [100, 1_109_333_293, 301, 188409]
print("Before del: ", my_list)
del my_list[1]
print("After del: ", my_list)

Before del: [100, 1109333293, 301, 188409]
After del: [100, 301, 188409]


Clearing the entire list

The clear() method deletes the entire elements in the list.

# Example
my_list = [303, 39222, 19, 0.12, 3.14]
print("Before clear(): ", my_list)
my_list.clear()
print("After clear(): ", my_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.

# Example
my_list = [10, 100, 1000, 10000, 1001000]
print("Before: ", my_list)

# Assign an empty list
my_list = [] 
print("After : ", my_list)

Before: [10, 100, 1000, 10000, 1001000]
After : []


Traversing the list

Lists in Python are sequential data structures and are linearly accessed.

Python provides two looping mechanisms discussed earlier:

  1. the for loop
  2. the while loop

Example

# Traversing using for loop

for <identifier> in <list>:
    # statement 1
    # statement 2
    ...
    ...
    # statement N

Example:

my_list = [1, "A", "B", "C", 2, 3, "D", 4]
for e in my_list:
    print(e)

1
A
B
C
2
3
D
4


Looping through items using an Index

Alternatively, you can also traverse the list by indexing the list, as demonstrated in the example below.

# Example
my_list = [8, 3, 0, 1, -1, 348, 3.14, "Hello, World"]
list_len = len(my_list)
for i in range(list_len):
    print(my_list[i])

8
3
0
1
-1
348
3.14
Hello, World

Let's break down each statement in the above example.

The statement  

my_list = [8, 3, 0, 1, -1, 348, 3.14, "Hello, World"]
defines a list.

The second statement  

list_len = len(my_list)
stores the current length of the list. This is required as this will inform us about the corresponding index values.

The statement for  

for i in range(list_len)
involves using the range() method. The range() method, as discussed earlier, takes the following arguments: starting_index, end_index, step; the latter two are optional.

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.


Using the while loop

Python provides the use of the while statement to iterator through a loop. Here is an example:

my_list = [8, 3, 0, 1, -1, 348, 3.14, "Hello, World"]
no_of_elements = len(my_list)
i = 0
while i < no_of_elements:
    print(my_list[i])

    # Update counter
    i += 1

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.


List shorthand

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.

# Iterating through the list to find even numbers and appending the same.
old_list = [9, 4, 0, 1, 2, 26, 28, 98, 21, 393]
even_numbers = []
for i in old_list:
    if i % 2 == 0:
        even_numbers.append(i)

print(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.

# Using the shorthand syntax
old_list = [9, 4, 0, 1, 2, 26, 28, 98, 21, 393]
even_numbers = [x for x in old_list if x % 2 == 0]
print(even_numbers)

[4, 0, 2, 26, 28, 98]

Now, let's break down the second statement as follows.

even_numbers = [x for x in old_list if x % 2 == 0]

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.


ADVERTISEMENT

Sorting Lists

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 = [5, 4, 3, 2, 1]
print("My List before sorting(): ", my_list)
my_list.sort()
print("My List after sorting(): ", my_list)

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:

my_list = [5, 4, 3, 2, 1]
print("My List before sorting(): ", my_list)
my_list.sort(reverse=True)
print("My List after sorting(): ", my_list)

The statement  

my_list.sort(reverse=True)
makes use of a yet uncovered feature, "named argument(s)" and will be covered later.

Remember to sort the list in descending order, use the "reverse=True" as an argument to the sort() method.


Reversing the List

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:

# Reverse a list
my_list = [11, 22, 33, 44]
print("Before reverse(): ", my_list)
my_list.reverse()
print("After reverse(): ", my_list)

Before reverse(): [11, 22, 33, 44]
After reverse(): [44, 33, 22, 11]


The copy() method

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.

# Example
original = [1, 2, 3]
new = original
new[0] = 8
print(original)
print(new)
print(original == new)
print(original is new)

[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.

original = [1, 2, 3]
new = original.copy()
new[0] = 8
print(original)
print(new)
print(original == new)
print(original is new)

[1, 2, 3]
[8, 2, 3]
False
False


Conclusion

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.


ADVERTISEMENT



All product names, logos, and brands are property of their respective owners.