Lists in Python
What is a List in Python?
A list in Python is a data type that stores multiple values, which can be of the same type, different types, or a combination of both. Lists can contain both unique and duplicate values.
- Its elements are enclosed in square brackets [ ] and separated by commas.
- It maintains the insertion order, meaning the order of elements remains as inserted.
- It is a mutable data type, allowing modifications after it is created.
- We can perform both indexing and slicing operations on a list object.
Syntax: list_ob = list[value1, value2, value3, ...]
# Example 1: Empty List using Square Brackets
l1 = []
print(l1, type(l1)) # Output: [] < class 'list' >
# Example 2: Empty List using the list() constructor
l1 = list()
print(l1, type(l1)) # Output: [] < class 'list' >
# Example 3: Non-empty List with Integer Values
l1 = [10, 20, 40, -23, 56, 890]
print(l1, type(l1)) # Output: [10, 20, 40, -23, 56, 890] < class 'list' >
# Example 4: Non-empty List with Mixed Data Types
l1 = [10, "Rossum", 45.67, True]
print(l1, type(l1)) # Output: [10, 'Rossum', 45.67, True] < class 'list' >
Operations on List Data in Python
On list data, we can perform two types of operations:
- Indexing:
- It helps access elements in a list, like the top score in a leaderboard.
- The index can be either positive or negative.
- If the index is valid, it returns the corresponding element.
- If the index is invalid, it raises an IndexError: list index out of range.
- Slicing:
- It returns elements from start to end-1 if start is less than end; otherwise, it returns an empty list.
- If slicing indices are out of range, Python slices within the valid range or returns empty sequence if the start index is too large.
Indexing is the process of retrieving a single element from a given `list` object using a valid index.
leaderboard = [950, 820, 780]
print(leaderboard[0]) # Gets 950
fruits = ['apple', 'banana', 'cherry']
print(fruits[-1]) # Output: cherry
fruits = ['apple', 'banana', 'cherry']
print(fruits[5]) # IndexError: list index out of range
Slicing is the process of retrieving a range of elements or a sub-list from a given `list` object using valid start and end indices.
# Example-1 : Get the first three students
students = ["Alice", "Bob", "Charlie", "David", "Eve"]
print(students[:3]) # ['Alice', 'Bob', 'Charlie']
# Example-2 : # Get every second temperature value
temperature_readings = [30.5, 32.0, 29.8, 31.2, 30.1, 33.3, 28.9]
print(temperature_readings[::2]) # [30.5, 29.8, 30.1, 28.9]
# Example-3: Get the list in reverse order
sentence = ["Python", "is", "a", "powerful", "language"]
print(sentence[::-1]) # ['language', 'powerful', 'a', 'is', 'Python']
Pre-defined functions in lists in Python
Here are the most commonly used useful functions:
- append():
- insert():
- clear():
- remove():
- pop(index):
- copy():
- count(value):
- index(value):
- reverse(value):
- sort(value):
- extend(iterable):
This function appends a new value to the end of the list.
Syntax: list_obj.append(value)
# Example-1: Add a new student to the list
students = ["Alice", "Bob", "Charlie"]
students.append("David")
print(students) # ['Alice', 'Bob', 'Charlie', 'David']
# Example-2: Append an item to a shopping list
shopping_list = ["Milk", "Eggs", "Bread"]
shopping_list.append("Butter")
print(shopping_list) # ['Milk', 'Eggs', 'Bread', 'Butter']
This function inserts a specified value at a valid index in the list, which can be positive or negative.
Syntax: list_obj.insert(index, value)
# Example-1: Add an element at the 2nd position (index 1)
fruits = ["Apple", "Banana", "Cherry"]
fruits.insert(1, "Mango")
print(fruits) # ['Apple', 'Mango', 'Banana', 'Cherry']
# Example-2: Add an element at the second-last position (negative index -1)
numbers = [10, 20, 30, 40]
numbers.insert(-1, 25)
print(numbers) # [10, 20, 30, 25, 40]
# Example-3: Add an element at an out-of-range index (appends at the end)
colors = ["Red", "Green", "Blue"]
colors.insert(10, "Yellow")
print(colors) # ['Red', 'Green', 'Blue', 'Yellow']
This function clears all elements from the list, making it empty.
Syntax: list_obj.clear()
# Example-1: Remove all elements from a list of numbers
numbers = [1, 2, 3, 4, 5]
numbers.clear()
print(numbers) # Output: []
# Example-2: Clear a list of strings
fruits = ["Apple", "Banana", "Cherry"]
fruits.clear()
print(fruits) # Output: []
This function removes the first occurrence of a specific item from a list. If the item is not found, it raises a ValueError.
Syntax: list_obj.remove(value)
# Example 1: Removes the first occurrence of 3
my_list = [1, 2, 3, 4, 3]
my_list.remove(3)
print(my_list) # Output: [1, 2, 4, 3]
# Example 2: Removes the first occurrence of "banana"
fruits = ["apple", "banana","banana", "cherry"]
fruits.remove("banana")
print(fruits) # Output: ["apple", "banana", "cherry"]
# Example 3: Raises ValueError because 40 is not in the list
numbers = [10, 20, 30]
numbers.remove(40) # Raises ValueError because 40 is not in the list
The pop() function removes and returns an element from a specified index (positive or negative). If no index is provided, it removes and returns the last element. If the index is invalid, it raises an IndexError.
Syntax: list_obj.pop(index) | list_obj.pop()
# Example-1: Remove an element using positive indexing
fruits = ["Apple", "Banana", "Cherry", "Kiwi"]
fruits.pop(1) # Removes "Banana" at index 1
print(fruits) # Output: ['Apple', 'Cherry', 'Kiwi']
# Example-2: Remove an element using negative indexing
numbers = [10, 20, 30, 40, 50]
numbers.pop(-2) # Removes 40 at index -2
print(numbers) # Output: [10, 20, 30, 50]
# Example-3: IndexError when using an out-of-range index
colors = ["Red", "Green", "Blue"]
colors.pop(5) # Raises IndexError: pop index out of range
# Example-4: Remove the last element from a list
animals = ["Dog", "Cat", "Elephant"]
animals.pop() # Removes "Elephant" (last element)
print(animals) # Output: ['Dog', 'Cat']
The copy() function creates a shallow copy of the list, allowing you to work with a new list while keeping the original list unchanged. When we use with sort(), it lets you sort a copy without affecting the original list.
Syntax: list_obj.copy()
# Example-1: Shallow copy of a list
original_list = [10, 20, 30, 40, 50]
shallow_copy = original_list.copy() # Shallow copy: new list but same elements
shallow_copy[0] = 100 # Modifies the first element of the shallow copy
print(original_list) # Output: [10, 20, 30, 40, 50]
# Example-2: Deep copy of a list
import copy
original_list = [10, 20, 30, 40, 50]
deep_copy = copy.deepcopy(original_list) # Deep copy: creates a completely new list
deep_copy[0] = 100 # Modifies the first element of the deep copy
print(original_list) # Output: [10, 20, 30, 40, 50]
The count() function is used to count the number of occurrences of a specified element. If the specified element is not found, count() returns 0.
Syntax: list_obj.count(value)
# Example-1: Count the occurrence of 2 in a list
my_list = [1, 2, 3, 4, 2, 5, 2]
count_of_twos = my_list.count(2)
print(count_of_twos) # Output: 3
# Example-2: Count the occurrence of 'apple' in a list
words_list = ['apple', 'banana', 'cherry', 'apple', 'orange']
count_of_apples = words_list.count('apple')
print(count_of_apples) # Output: 2
# Example-3: Count the occurrence of 'grape' in a list
fruit_list = ['apple', 'banana', 'cherry', 'orange']
count_of_grapes = fruit_list.count('grape')
print(count_of_grapes) # Output: 0
The index() function in a list returns the index of the first occurrence of a specified element. If the element is not found, it raises a ValueError.
Syntax: list_obj.index(value)
# Example-1: Find the index of the first occurrence of 2 in a list
my_list = [1, 2, 3, 4, 2, 5, 2]
index_of_two = my_list.index(2)
print(index_of_two) # Output: 1
# Example-2: Find the index of the first occurrence of 'John' in a list
students = ['Alice', 'Bob', 'Charlie', 'David']
index_of_john = students.index('John') # This will raise ValueError: 'John' is not in list
The reverse() function in a list reverses the order of the elements in the list. It modifies the original list directly and does not return a new list.
Syntax: list_obj.index(value)
# Example-1: Reverse the order of a list of numbers
numbers = [1, 2, 3, 4, 5]
numbers.reverse() # Reverses the list in place
print(numbers) # Output: [5, 4, 3, 2, 1]
# Example-2: Reverse the order of words in a list of words
words = ['apple', 'banana', 'cherry']
words.reverse() # Reverses the list in place
print(words) # Output: ['cherry', 'banana', 'apple']
The sort() function sorts the elements of a list in ascending order by default, modifying the original list in place. You can also customize the order using parameters like reverse=True or key.
Syntax: list_obj.index(value)
# Example-1: Sort a list of student scores in ascending order
student_scores = [75, 82, 60, 95, 88, 72]
student_scores.sort() # Sorts the scores in ascending order
print("Sorted student scores:", student_scores) # Output: [60, 72, 75, 82, 88, 95]
# Example-2: Sort a list of student names in ascending order
students = ['David', 'Eve', 'Charlie', 'Frank', 'Alice', 'Bob']
students.sort() # Sorts the student names in ascending alphabetical order
print(students) # Output: ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank']
The extend() function adds all elements of another iterable (such as a list, tuple, or set) to the end of the current list. It modifies the original list directly.
Syntax: list_obj.extend(iterable)
# Example-1: Add multiple names to an existing list of attendees
attendees = ['Alice', 'Bob', 'Charlie']
new_attendees = ['David', 'Eve']
attendees.extend(new_attendees) # Adds new attendees to the existing list
print(attendees) # Output: ['Alice', 'Bob', 'Charlie', 'David', 'Eve']
# Example-2: Add more numbers to an existing list of scores
scores = [85, 90, 92]
additional_scores = (78, 88, 94)
scores.extend(additional_scores) # Adds additional scores to the list
print(scores) # Output: [85, 90, 92, 78, 88, 94]
What are Inner or Nested Lists in Python?
In Python, defining a list inside another list is called a nested list or inner list. It allows hierarchical data storage, enabling multi-dimensional structures like matrices.
- We can perform both indexing and slicing operations on nested lists in Python.
- We can use all predefined functions on nested lists in Python.
Syntax: nested_list = [[elem1, elem2], [elem3, elem4], [elem5, elem6]]
# Example-1: Storing and Accessing Student Grades
grades = [["Alice", [85, 90, 92]], ["Bob", [78, 88, 80]], ["Charlie", [95, 91, 89]]]
print(grades[0]) # Output: ['Alice', [85, 90, 92]]
print(grades[1][1][2]) # Output: 80 (Bob's third grade)
# Example-2: Slicing a 3x3 Matrix
matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
# Extract the first two rows
print(matrix[:2]) # Output: [[1, 2, 3], [4, 5, 6]]
# Extract the last two columns
print([row[1:] for row in matrix]) # Output: [[2, 3], [5, 6], [8, 9]]
Exercise
- Top 5 Python Problems on Slicing, Indexing & Nested Lists:
- - Write a Python program to reverse the string "Python" using slicing.
- - Given a list [10, 20, 30, 40, 50], extract [20, 30, 40] using slicing.
- - From [[1, 2, 3], [4, 5, 6], [7, 8, 9]], extract 5 using indexing.
- - Swap the first and last elements of [5, 10, 15, 20].
- - Get [1, 5, 9] from [[1,2,3],[4,5,6],[7,8,9]] using indexing.