Python List

Python List Tutorial

Introduction:

Lists are one of the most commonly used data structures in Python. A list is a collection of elements, which can be of any type, including numbers, strings, and other lists etc. Lists are mutable, which means you can make changes in the list by adding, removing, or changing elements.

List declaration:

To declare a list in Python, you can use square brackets [] and separate the elements with commas. Here’s an example:

				
					new_list = [ 1, 2, 3, 4, 5 ]
				
			

In the above example, we created a list called new_list that contains five integers.

You can also create an empty list by using the list() function or just an empty set of square brackets [].  Here are some examples:

				
					list_1 = list()
list_2 = []

				
			

Both of the examples above create an empty list called empty_list_1 and list_2.

				
					#Printing the type of the list
print( type ( list_1 ) ) # Output : < class ' list ' >
print( type ( list_2 ) ) # Output : < class ' list ' >

				
			

You can also create a list of a specific size filled with a default value using the * operator.  Here’s an example:

				
					my_list = [ 1 ] * 3
print( my_list )  # Output : [ 1, 1, 1 ]

				
			

In the example above, we created a list called my_list that contains three 1 values.

				
					#Printing the type of the list
print( type( my_list ) ) # Output : < class ' list ' >

				
			

List Rules:

  1. List elements can be of different data types, including integers, floats, strings, booleans, and other objects.
  2. Lists are mutable, which means that we can modify it by adding, removing, or changing elements.
  3. Index of elements in the list starts from 0. We can access individual elements of a list by their index.
  4. We can use slicing to extract a subset of elements from a list. Slicing returns a new list that includes the specified range of elements.
  5. Lists can be concatenated using the ‘+’ operator.
  6. Lists can be nested, meaning that you can have a list of lists.
  7. Lists can be sorted in ascending or descending order using the sorted() function or the sort() method.
  8. We can use the len() function to get the number of elements in a list.
  9. We can iterate over the elements of a list using a for loop or list comprehension.
  10. Two lists can be compared for equality using the ‘==’ operator. Two lists are considered equal if they have the same elements in the same order.

Python list features:

  1. Mutable: Lists are mutable, meaning you can modify their elements by assigning new values to specific indices.
  2. Ordered: Lists maintain the order of elements as they are added. The first element added will be at index 0, the second element at index 1, and so on.
  3. Dynamic Size: Python lists can dynamically grow or shrink in size as elements are added or removed. You don’t need to specify the size beforehand.
  4. Heterogeneous Elements: Lists can contain elements of different data types. For example, a single list can store integers, floats, strings, or even other lists.
  5. Indexing and Slicing: You can access individual elements in a list using square brackets notation and their index. Additionally, you can slice lists to extract a portion of elements by specifying start and end indices.
  6. Iteration: Lists can be easily iterated over using loops or list comprehensions, allowing you to process each element or perform operations on the entire list.
  7. Built-in Functions: Python provides a range of built-in functions specifically designed for working with lists. These include functions like `len()`, `max()`, `min()`, `sum()`, `sorted()`, and more.
  8. Versatile Data Structure: Lists are a versatile data structure used in a variety of scenarios. They are commonly used for storing collections of related items, implementing stacks, queues, and other data structures, and for general-purpose data manipulation.
  9. List Comprehensions: Python allows you to create new lists by performing operations on existing lists using concise and expressive syntax called list comprehensions. This feature provides an efficient and readable way to manipulate lists.
  10. Extensive Methods: Python lists come with a range of built-in methods that enable various operations like adding or removing elements, sorting, reversing, searching, and more. These methods make it easy to work with lists and perform common list operations efficiently.

Python list advantages:

  1. Flexibility: Python lists are highly flexible and versatile. They can store elements of different data types, allowing you to create lists with a mix of integers, floats, strings, and other objects. This flexibility makes lists suitable for a wide range of applications.
  2. Dynamic Size: Lists in Python can grow or shrink dynamically as elements are added or removed. Unlike some other programming languages, you don’t need to specify the size of a list beforehand. This dynamic resizing capability makes it convenient to work with collections of varying lengths.
  3. Easy Element Manipulation: Python provides intuitive ways to manipulate list elements. You can easily access, modify, or delete elements based on their indices. This makes it convenient to update or rearrange elements within a list as needed.
  4. Iteration and Looping: Python lists can be easily iterated over using loops or list comprehensions. This allows you to process each element in a list sequentially or apply operations to the entire list, making it straightforward to perform calculations or transformations on list data.
  5. Built-in Functions and Methods: Python provides a rich set of built-in functions and methods specifically designed for working with lists. These functions and methods simplify common list operations such as sorting, searching, filtering, adding or removing elements, and more. This extensive set of tools saves you time and effort when working with lists.
  6. Powerful List Comprehensions: Python offers list comprehensions, which are concise and expressive ways to create new lists based on existing ones. List comprehensions allow you to apply transformations, conditions, and calculations to existing lists in a single line of code, making your code more readable and compact.
  7. Compatibility with Other Data Structures: Lists in Python can easily be converted to and from other data structures like tuples or arrays. This compatibility allows you to take advantage of the specific features and benefits offered by different data structures as needed.
  8. Common Data Structure: Python lists are widely used and well-supported. They are a fundamental data structure in Python, and you’ll find them extensively used in libraries, frameworks, and code examples. This popularity means that there is a wealth of resources, documentation, and community support available for working with lists.

Python list disadvantages:

  1. Slow for Large Data Sets: Python lists may become inefficient when dealing with large data sets or performing operations that require frequent insertions or deletions. As lists are dynamically resized, these operations can be time-consuming, particularly if the list needs to be resized multiple times.
  2. Sequential Search: When searching for an element in a list, Python performs a sequential search, iterating through each element until a match is found. This linear search approach can be slow for large lists, especially when compared to more efficient search algorithms like binary search available for sorted arrays.
  3. Fixed Overhead: Each element in a Python list requires additional memory to store its value and associated metadata, such as the data type and object reference. This fixed overhead per element can be significant when dealing with large lists, potentially consuming more memory than other data structures optimized for memory efficiency.
  4. Lack of Constant-Time Operations: Certain operations on Python lists, such as inserting or removing an element at a specific index, can be slow for large lists. These operations may require shifting or reassigning elements, resulting in a time complexity of O(n), where n is the number of elements in the list. In contrast, other data structures like arrays or linked lists can provide constant-time operations for these operations.
  5. Limited Sorting Options: Python’s built-in sorting method, `list.sort()`, uses a variant of the quicksort algorithm. While it is efficient in most cases, it may not be suitable for certain specialized sorting requirements. For such scenarios, you may need to implement custom sorting algorithms or explore external libraries for specific sorting needs.
  6. Not Suitable for Unique Elements: Python lists can contain duplicate elements. If you require a collection that only allows unique elements, you need to perform additional checks or use alternative data structures like sets or dictionaries.
  7. Mutable Nature: While mutability can be an advantage, it can also lead to unintended changes in list elements. If a list is shared among multiple parts of a program or passed as a parameter to functions, modifying the list can affect other parts of the code unintentionally. This can lead to potential bugs or unexpected behavior.

Python List Indexing and Slicing

In Python first element in the list has an index of 0. You can access elements in a list by their index using square brackets. Here’s an example:

				
					new_list = [ 1, 2, 3, 4, 5 ]
print( new_list[ 0 ] )  # Output : 1
print( new_list[ 3 ] )  # Output : 4

				
			

You can also use negative indexing to access the list elements in the reverse order. Here’s an example:

				
					new_list = [ 1, 2, 3, 4, 5 ]
print( new_list[-1])  # Output : 5
print( new_list[ -3 ] ) # Output : 3

				
			
Slicing rules to created sublist in python:

Here are the rules for slicing in Python:

  1. Slicing uses the colon : operator to specify a range of indices. The syntax is my_list[start_index:end_index:step].
  2. The start_index is the index of the first element to include in the slice. If not specified, it defaults to 0.
  3. The end_index is the index of the first element to exclude from the slice. If not specified, it defaults to the length of the list.
  4. The step parameter specifies the step size between elements in the slice. If not specified, it defaults to 1.
  5. All parameters can be negative, in which case they specify the index relative to the end of the list. For example, my_list[-1] refers to the last element of the list.
  6. Slicing returns a new list that contains the specified range of elements from the original list.

You can also use slicing to access a subset of the list. Slicing allows you to extract a range of elements from the list. Here’s an example:

				
					new_list = [ 1, 2, 3, 4, 5 ]
print( new_list[ 0 : 2 ] )  # Output : [ 1,2,3 ]
print( new_list[ 1 : 4 ] ) # Output : [ 2,3,4,5 ]

				
			

In the example above, we used slicing to extract a subset of the list that starts at index 0 and ends at index 3 ( not including index 3 ).

Python List Methods:

Lists in Python have many built-in methods that you can use to modify or manipulate the list. Here are some of the most commonly used methods:

  1. append() – It is used to add an element to the end of the list.
				
					new_list = [ 1, 2, 3, 4, {} ]
new_list.append( 6 )
print( new_list )  # Output : [ 1, 2, 3, 4, {}, 6 ]

new_list = [ 1, 2, 3, 4, {} ]
new_list.append( “sqatools” )
print( new_list )  # Output : [ 1, 2, 3, 4, {}, “sqatools” ]

				
			
  1. extend() – It is used to add the elements of another list to the end of the list or to combine two lists.
				
					new_list = [ 1, 2, 3, 4, 5 ]
new_list.extend( [ [], 8, 9, 10 ] )
print( new_list )  # Output : [ 1, 2, 3, 4, 5, [], 8, 9,10 ]

new_list = [ 1, 2, 3, 4, 5 ]
new_list.extend( [ [], 8.2, 9, {} ] )
print( new_list )  # Output : [1, 2, 3, 4, 5, [], 8.2, 9, {} ]

				
			
  1. insert() – It is used to insert an element at a specific position in the list.
				
					new_list = [ 1, 2, 3, 4, 5 ]
new_list.insert( 3 , 6 )
print( new_list )  # Output : [ 1, 2, 3, 6, 4, 5 ]
#Here, we inserted 6 at the 3rd index number in the list.

new_list = [ 1, 2, 3, 4, 5 ]
new_list.insert( 4, ‘sqatools’ )
print( new_list )  # Output : [ 1, 2, 3, 6, 4, ‘sqatools’ ]
#Here, we inserted ‘sqatools’ at the 4th index number in the list.

				
			

         4. remove() – It is used to remove the first occurrence of an element from the list.

				
					new_list = [ 1, 2, 3, 4, 5 ]
new_list.remove( 4 )
print( new_list ) # Output : [ 1, 2, 3, 5 ]

new_list = [ 1, 2, 3, ‘sqatools’, 5 ]
new_list.remove( ‘sqatools’ )
print( new_list ) # Output : [ 1, 2, 3, 5 ]

				
			
  1. pop() – It removes and returns the element at a specific position in the list.
				
					new_list = [ 1, 2, 3, 4, 5 ]
new_list.pop( 4 )
print( new_list ) # Output : [ 1, 2, 3, 4 ]

new_list = [ 1, 2, 3, 4, { ‘key’ : ’value’ } ]
new_list.pop(4)
print( new_list ) # Output : [ 1, 2, 3, 4 ]

				
			

          6. sort() – It sorts the elements of the list in ascending order.

				
					new_list = [ 3, 6, 4, 5 ]
new_list.sort()
print( new_list ) # Output : [ 3, 4, 5, 6 ]

new_list = [ 3, 6, 4, 5, 0, -5 ]
new_list.sort()
print( new_list ) # Output : [ -5, 0, 3, 4, 5, 6 ]

				
			

          7 .reverse() – It reverses the order of the elements in the list.

				
					new_list = [ 1, 2, 3, 4, 5 ]
new_list.reverse()
print( new_list ) # Output : [ 5,  4,  3 , 2,  1 ]  

				
			
  1. clear() – It is used to remove all elements from a list, effectively emptying the list. After the clear() function is applied to a list, the list becomes empty with a length of 0.
				
					new_list = [ 1, 2, 3, 4, 5 ]
new_list.clear()
print( new_list ) # Output : [  ]

				
			
  1. copy() – It creates a shallow copy of a list. The shallow copy means that a new list is created with the same elements as the original list, but the elements themselves are not duplicated. Any changes made to the elements in the copied list will also affect the original list, and vice versa.
				
					# Original list with elements
original_list = [1, 2, 3, [4, 5]]
# Create a shallow copy of the list using the copy() function
copied_list = original_list.copy()
# Modify an element in the copied list
copied_list[3][0] = 1

# Both the original and copied lists are affected
print(original_list)  # Output: [1, 2, 3, [1, 5]]
print(copied_list)    # Output: [1, 2, 3, [1, 5]]

				
			
  1. index() – It is used to find the index of the first occurrence of a specified element within a list. If the element is not found in the list, it raises a ValueError.
				
					new_list = [ 1, 2, 3, 4, 5 ]
print(index(2)) # Output : 1

				
			
  1. count() – It is used to count the number of occurrences of a specified element in a list.
				
					new_list = [ 1, 2, 3, 4, 5, 1 ]
print(count(1)) # Output : 2

				
			

Updating list values:

Lists in Python are mutable, and their values can be updated by using the slice and assignment the ( = ) operator.

				
					new_list = [ 1, 2, 3, 4, 5 ]
print( new_list ) # Output : [ 1, 2, 3, 4, 5 ]

# Updating 2nd element in the list
new_list[ 1 ] = 15
print( new_list ) # Output : [ 1, 15, 3, 4, 5 ]

				
			

Built-in function for Python lists:

Here are some examples of commonly used built-in functions for lists in Python:

  1. len(): It returns the length of the list.
				
					new_list = [ 1, 2, 3, 4, 5 ]
print( len ( new_list ) )  # Output : 5

new_list = [ ‘Python’,20.5,False ]
print ( len ( new_list ) ) #Output : 3

				
			
  1. max(): It returns the largest element in the list.
				
					new_list = [1, 2, 3, 4, 5]
print( max ( new_list ) )  # Output : 5

				
			
  1. min(): It returns the smallest element in the list.
				
					new_list = [ 1, 2, 3, 4, 5 ]
print( min ( new_list) )  # Output : 1

				
			
  1. sum(): It returns the sum of all elements in the list.
				
					new_list = [ 1, 2, 3, 4, 5 ]
print( sum ( new_list ) )  # Output : 15

				
			

       5. sorted(): It returns a new sorted list.

				
					new_list = [ 5, 1, 4, 2, 3 ]
sorted_list = sorted( new_list )
print( sorted_list )  # Output: [ 1, 2, 3, 4, 5 ]

				
			
  1. list(): It converts an iterable to a list.
				
					my_tuple = ( 1, 2, 3, 4, 5 )
new_list = list( my_tuple )
print( new_list )  # Output: [ 1, 2, 3, 4, 5 ]

my_set = { 1, 2, 3, 4, 5 }
new_list = list( my_set )
print( new_list ) #Output: [ 1, 2, 3, 4, 5 ]

				
			

       7. any(): It returns True if at least one element in the list is True.

				
					new_list = [ False, False, True ]
print( any ( new_list ) )  # Output: True

new_list =  [False, False, False, False ]
print( any( new_list ) ) # Output: False

				
			
  1. all(): It returns True if all elements in the list are True.
				
					new_list = [ True, True, False ]
print(all( new_list ))  # Output: False

new_list = [ True, True, True ]
print( all( new_list ) )  # Output: True

				
			

        9. enumerate(): It returns an iterator that contains tuples of (index, element) pairs.

				
					new_list = [ 1, 2, 3, 4, 5 ]
for index, element in enumerate( new_list ):
    print( index, element )
# Output:
0 1
1 2
2 3
3 4
4 5

				
			
  1. zip(): It returns an iterator that aggregates elements from multiple lists into tuples.
				
					new_list_1 = [ 1, 2, 3 ]
new_list_2 = [ "one", "two", "three" ]
for number, word in zip( new_list_1 , new_list_2):
    print( number, word )
# Output:
1 one
2 two
3 three

				
			

        11.reversed(): It returns a reverse iterator that can be used to iterate over a list in reverse order.

				
					new_list_1 = [ 1, 2, 3, 4, 5 ]
new_list_2 = reversed( new_list_1 ) 
print( new_list_2 ) # Output: [ 5, 4, 3, 2, 1 ]

				
			

Iterating over a list

We can use a for loop to iterate over the list elements. Here’s an example:

				
					new_list = [ 1, 2, 3, 4, 5 ]
for element in new_list:
	print( element )
# Output:
1
2
3
4
5

				
			

Membership operator in list

We can use operator (i.e. in or not in) on list elements. If an element is in list then it returns True. If an element is not in list it return False. Here’s an example:

				
					new_list = [ 1, 2, 3, 4, 5 ]
print( 2 in new_list ) #Output: True
print( 3 not in new_list ) #Output: False 

				
			

Repetition on list

We can use * operator for repetition of list. Here’s an example:

				
					new_list = [ 1, 2, 3, 4, 5 ]
print( new_list * 2 ) # Output : [ 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 ]

				
			

Concatenation on list

We can use + operator for concatenation of list. Here’s an example:

				
					new_list_1 = [ 1, 2, 3, 4, 5 ]
new_list_2 = [ 6, 7, 8, 9, 10 ]
print( new_list_1 * new_list_2 ) # Output : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

				
			

List Comprehension

List comprehension is a concise and expressive way of creating lists in Python. It allows you to define a list and its elements within a single line of code, combining the functionality of a for loop, optional if conditions, and even nested loops. List comprehensions are preferred for their readability and efficiency compared to traditional for loops.

  1. Simple For Loop List Comprehension:

This type of list comprehension is used to create a list by iterating over elements from an iterable (e.g., list, tuple, string) without any filtering or conditions. Here’s an example:

				
					# Using a simple for loop list comprehension to create a list of squares
numbers = [1, 2, 3, 4, 5]
squares = [num**2 for num in numbers]
# Output: [1, 4, 9, 16, 25]

				
			
  1. Loop and If Condition List Comprehension:

This type of list comprehension includes an if condition to filter elements while iterating over the iterable. Only elements that satisfy the condition are included in the new list. Here’s an example:

				
					# Using loop and if condition list comprehension to filter even numbers
numbers = [1, 2, 3, 4, 5]
even_numbers = [num for num in numbers if num % 2 == 0]
# Output: [2, 4]

				
			
  1. Loop and If-Else Condition List Comprehension:

This type of list comprehension allows you to perform different operations based on the if-else condition while iterating over the iterable. Here’s an example:

				
					# Using loop and if-else condition list comprehension to classify numbers as even or odd
numbers = [1, 2, 3, 4, 5]
even_odd = ['even' if num % 2 == 0 else 'odd' for num in numbers]
# Output: ['odd', 'even', 'odd', 'even', 'odd']

				
			
  1. Nested Loop List Comprehension:

This type of list comprehension allows you to use nested loops for creating more complex lists by iterating over multiple iterables simultaneously. Here’s an example:

				
					# Using nested loop list comprehension to create a list of tuples containing pairs from two lists
letters = ['a', 'b']
numbers = [1, 2, 3]
pairs = [(letter, num) for letter in letters for num in numbers]
# Output: [('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3)]

				
			

Shallow Copy and Deep Copy of Lists in Python:

In Python, when dealing with lists or other compound data structures, understanding the concepts of shallow copy and deep copy is crucial. Both concepts involve creating a new copy of an existing list, but they differ in how they handle nested objects within the list.

  1. Shallow Copy:

A shallow copy of a list creates a new list object but does not create copies of the elements inside the list. Instead, it copies references to the original objects. This means that changes made to nested objects within the copied list will affect the original list, and vice versa. To perform a shallow copy, you can use the `copy()` method or the slicing notation `[:]`. Example of Shallow Copy:

				
					# Original list with nested objects
original_list = [1, 2, 3, [4, 5]]

# Creating a shallow copy of the list
shallow_copy = original_list.copy()

# Modifying a nested list in the copied list
shallow_copy [3][0] = 1

# Both the original and copied lists are affected
print(original_list)  # Output: [1, 2, 3, [1, 5]]
print(shallow_copy)  # Output: [1, 2, 3, [1, 5]]

				
			
  1. Deep Copy:

A deep copy of a list creates a new list object and also recursively creates copies of all the nested objects within the original list. In other words, the copied list and its nested objects are entirely independent of the original list and its nested objects. To perform a deep copy, you need to use the `deepcopy()` function from the `copy` module. Example of Deep Copy:

				
					# Importing the deepcopy function from the copy module
from copy import deepcopy

# Original list with nested objects
original_list = [1, 2, 3, [4, 5]]

# Creating a deep copy of the list
deep_copy = deepcopy(original_list)

# Modifying a nested list in the copied list
deep_copy [3][0] = 1

# Only the copied list is affected, the original list remains unchanged
print(original_list)  # Output: [1, 2, 3, [4, 5]]
print(deep_copy)  # Output: : [1, 2, 3, [1, 5]]

				
			

Shallow copy is faster and suitable when you want to create a new list but share references to nested objects. Deep copy is appropriate when you need an entirely independent copy of the original list and all its nested objects.

Leave a Comment