Blog

  • Unpack Tuple Items

    Unpack Tuple Items

    The term “unpacking” refers to the process of parsing tuple items in individual variables. In Python, the parentheses are the default delimiters for a literal representation of sequence object.

    Following statements to declare a tuple are identical.

    >>> t1 =(x,y)>>> t1 = x,y
    >>>type(t1)<class'tuple'>

    Example

    To store tuple items in individual variables, use multiple variables on the left of assignment operator, as shown in the following example −

    tup1 =(10,20,30)
    x, y, z = tup1
    print("x: ", x,"y: ","z: ",z)

    It will produce the following output −

    x: 10 y: 20 z: 30
    

    That’s how the tuple is unpacked in individual variables.

    In the above example, the number of variables on the left of assignment operator is equal to the items in the tuple. What if the number is not equal to the items?

    ValueError While Unpacking a Tuple

    If the number of variables is more or less than the length of tuple, Python raises a ValueError.

    Example

    tup1 =(10,20,30)
    x, y = tup1
    x, y, p, q = tup1
    

    It will produce the following output −

      x, y = tup1
      ^^^^
    ValueError: too many values to unpack (expected 2)
      x, y, p, q = tup1
      ^^^^^^^^^^
    ValueError: not enough values to unpack (expected 4, got 3)
    

    Unpack Tuple Items Using Asterisk (*)

    In such a case, the “*” symbol is used for unpacking. Prefix “*” to “y”, as shown below −

    Example 1

    tup1 =(10,20,30)
    x,*y = tup1
    print("x: ","y: ", y)

    It will produce the following output −

    x: y: [20, 30]
    

    The first value in tuple is assigned to “x”, and rest of items to “y” which becomes a list.

    Example 2

    In this example, the tuple contains 6 values and variables to be unpacked are 3. We prefix “*” to the second variable.

    tup1 =(10,20,30,40,50,60)
    x,*y, z = tup1
    print("x: ",x,"y: ", y,"z: ", z)

    It will produce the following output −

    x: 10 y: [20, 30, 40, 50] z: 60
    

    Here, values are unpacked in “x” and “z” first, and then the rest of values are assigned to “y” as a list.

    Example 3

    What if we add “*” to the first variable?

    tup1 =(10,20,30,40,50,60)*x, y, z = tup1
    print("x: ",x,"y: ", y,"z: ", z)

    It will produce the following output −

    x: [10, 20, 30, 40] y: 50 z: 60
    

    Here again, the tuple is unpacked in such a way that individual variables take up the value first, leaving the remaining values to the list “x”.

  •  Update Tuples

    Updating Tuples in Python

    In Python, tuple is an immutable sequence, meaning once a tuple is created, its elements cannot be changed, added, or removed.

    To update a tuple in Python, you can combine various operations to create a new tuple. For instance, you can concatenate tuples, slice them, or use tuple unpacking to achieve the desired result. This often involves converting the tuple to a list, making the necessary modifications, and then converting it back to a tuple.

    Updating Tuples Using Concatenation Operator

    The concatenation operator in Python, denoted by +, is used to join two sequences, such as strings, lists, or tuples, into a single sequence. When applied to tuples, the concatenation operator joins the elements of the two (or more) tuples to create a new tuple containing all the elements from both tuples.

    We can update a tuple using the concatenation operator by creating a new tuple that combines the original tuple with additional elements.

    Since tuples are immutable, updating tuples using concatenation operator does not modify the original tuple but instead creates a new one with the desired elements.

    Example

    In the following example, we create a new tuple by concatenating “T1” with “T2” using the “+” operator −

    # Original tuple
    T1 =(10,20,30,40)# Tuple to be concatenated
    T2 =('one','two','three','four')# Updating the tuple using the concatenation operator
    T1 = T1 + T2
    print(T1)

    It will produce the following output −

    (10, 20, 30, 40, 'one', 'two', 'three', 'four')
    

    Updating Tuples Using Slicing

    Slicing in Python is used to extract a portion of a sequence (such as a list, tuple, or string) by specifying a range of indices. The syntax for slicing is as follows −

    sequence[start:stop:step]

    Where,

    • start is the index at which the slice begins (inclusive).
    • stop is the index at which the slice ends (exclusive).
    • step is the interval between elements in the slice (optional).

    We can update a tuple using slicing by creating a new tuple that includes slices of the original tuple combined with new elements.

    Example

    In this example, we are updating a tuple by slicing it into two parts and inserting new elements between the slices −

    # Original tuple
    T1 =(37,14,95,40)# Elements to be added
    new_elements =('green','blue','red','pink')# Extracting slices of the original tuple# Elements before index 2
    part1 = T1[:2]# Elements from index 2 onward
    part2 = T1[2:]# Create a new tuple 
    updated_tuple = part1 + new_elements + part2
    # Printing the updated tupleprint("Original Tuple:", T1)print("Updated Tuple:", updated_tuple)

    Following is the output of the above code −

    Original Tuple: (37, 14, 95, 40)
    Updated Tuple: (37, 14, 'green', 'blue', 'red', 'pink', 95, 40)
    

    Updating Tuples Using List Comprehension

    List comprehension in Python is a concise way to create lists. It allows you to generate new lists by applying an expression to each item in an existing iterable, such as a list, tuple, or string, optionally including a condition to filter elements.

    Since tuples are immutable, updating a tuple involves converting it to a list, making the desired changes using list comprehension, and then converting it back to a tuple.

    Example

    In the example below, we are updating a tuple by first converting it to a list and using list comprehension to add 100 to each element. We then convert the list back to a tuple to get the updated tuple −

    # Original tuple
    T1 =(10,20,30,40)# Converting the tuple to a list
    list_T1 =list(T1)# Using list comprehension 
    updated_list =[item +100for item in list_T1]# Converting the updated list back to a tuple
    updated_tuple =tuple(updated_list)# Printing the updated tupleprint("Original Tuple:", T1)print("Updated Tuple:", updated_tuple)

    Output of the above code is as follows −

    Original Tuple: (10, 20, 30, 40)
    Updated Tuple: (110, 120, 130, 140)
    

    Updating Tuples Using append() function

    The append() function is used to add a single element to the end of a list. However, since tuples are immutable, the append() function cannot be directly used to update a tuple.

    To update a tuple using the append() function, we need to first convert the tuple to a list, then use append() to add elements, and finally convert the list back to a tuple.

    Example

    In the following example, we first convert the original tuple “T1” to a list “list_T1”. We then use a loop to iterate over the new elements and append each one to the list using the append() function. Finally, we convert the updated list back to a tuple to get the updated tuple −

    # Original tuple
    T1 =(10,20,30,40)# Convert tuple to list
    list_T1 =list(T1)# Elements to be added
    new_elements =[50,60,70]# Updating the list using append()for element in new_elements:
    
    list_T1.append(element)# Converting list back to tuple
    updated_tuple =tuple(list_T1)# Printing the updated tupleprint("Original Tuple:", T1)print("Updated Tuple:", updated_tuple)

    We get the output as shown below −

    Original Tuple: (10, 20, 30, 40)
    Updated Tuple: (10, 20, 30, 40, 50, 60, 70)
  • Access Tuple Items

    Access Tuple Items

    The most common way to access values within a Python tuple is using indexing, We just need to specify the index of the elements we want to retrieve to the square bracket [] notation.

    In Python, a tuple is an immutable ordered collection of elements. “Immutable” means that once a tuple is created, we cannot modify or change its contents. We can use tuples to group together related data elements, similar to lists, but with the key difference that tuples are immutable, while lists are mutable.

    In addition to indexing, Python provides various other ways to access tuple items such as slicing, negative indexing, extracting a subtuple from a tuple etc. Let us go through this one-by-one −

    Accessing Tuple Items with Indexing

    Each element in a tuple corresponds to an index. The index starts from 0 for the first element and increments by one for each subsequent element. Index of the last item in the tuple is always “length-1”, where “length” represents the total number of items in the tuple. To access the elements of a tuple we just need to specify the index of the item we need to access/retrieve, as shown below −

    tuple[3]

    Example

    Following is the basic example to access tuple items with slicing index −

    Open Compiler

    tuple1 =("Rohan","Physics",21,69.75)
    tuple2 =(1,2,3,4,5)print("Item at 0th index in tuple1: ", tuple1[0])print("Item at index 2 in tuple2: ", tuple2[2])

    It will produce the following output −

    Item at 0th index in tuple1:  Rohan
    Item at index 2 in tuple2:  3
    

    Accessing Tuple Items with Negative Indexing

    Negative indexing in Python is used to access elements from the end of a tuple, with -1 referring to the last element, -2 to the second last, and so on.

    We can also access tuple items with negative indexing by using negative integers to represent positions from the end of the tuple.

    Example

    In the following example, we are accessing tuple items with negative indexing −

    Open Compiler

    tup1 =("a","b","c","d")
    tup2 =(25.50,True,-55,1+2j)print("Item at 0th index in tup1: ", tup1[-1])print("Item at index 2 in tup2: ", tup2[-3])

    We get the output as shown below −

    Item at 0th index in tup1:  d
    Item at index 2 in tup2:  True
    

    Accessing Range of Tuple Items with Negative Indexing

    By range of tuple items, we mean accessing a subset of elements from a tuple using slicing. Therefore, we can access a range of tuple items with negative indexing by using the slicing operation in Python.

    Example

    In the example below, we are accessing a range of tuple items by using negative indexing −

    Open Compiler

    tup1 =("a","b","c","d")
    tup2 =(1,2,3,4,5)print("Items from index 1 to last in tup1: ", tup1[1:])print("Items from index 2 to last in tup2", tup2[2:-1])

    It will produce the following output −

    Items from index 1 to last in tup1: ('b', 'c', 'd')
    Items from index 2 to last in tup2: (3, 4)
    

    Access Tuple Items with Slice Operator

    The slice operator in Python is used to fetch one or more items from the tuple. We can access tuple items with the slice operator by specifying the range of indices we want to extract. It uses the following syntax −

    [start:stop]

    Where,

    • start is the starting index (inclusive).
    • stop is the ending index (exclusive).

    Example

    In the following example, we are retrieving subtuple from index 1 to last in “tuple1” and index 0 to 1 in “tuple2”, and retrieving all elements in “tuple3” −

    tuple1 =("a","b","c","d")
    tuple2 =(25.50,True,-55,1+2j)
    tuple3 =(1,2,3,4,5)
    tuple4 =("Rohan","Physics",21,69.75)print("Items from index 1 to last in tuple1: ", tuple1[1:])print("Items from index 0 to 1 in tuple2: ", tuple2[:2])print("Items from index 0 to index last in tuple3", tuple3[:])

    Following is the output of the above code −

    Items from index 1 to last in tuple1:  ('b', 'c', 'd')
    Items from index 0 to 1 in tuple2:  (25.5, True)
    Items from index 0 to index last in tuple3 ('Rohan', 'Physics', 21, 69.75)
    

    Accessing Sub Tuple from a Tuple

    A subtuple is a part of a tuple that consists of a consecutive sequence of elements from the original tuple.

    We can access a subtuple from a tuple by using the slice operator with appropriate start and stop indices. It uses the following syntax −

    my_tuple[start:stop]

    Where,

    • start is the starting index (inclusive).
    • stop is the ending index (exclusive) of the subtuple.

    If we does not provide any indices, the slice operator defaults to starting from index 0 and stopping at the last item in the tuple.

    Example

    In this example, we are fetching subtuple from index “1 to 2” in “tuple1” and index “0 to 1” in “tuple2” using slice operator −

    tuple1 =("a","b","c","d")
    tuple2 =(25.50,True,-55,1+2j)print("Items from index 1 to 2 in tuple1: ", tuple1[1:3])print("Items from index 0 to 1 in tuple2: ", tuple2[0:2])

    The output obtained is as follows −

    Items from index 1 to 2 in tuple1:  ('b', 'c')
    Items from index 0 to 1 in tuple2:  (25.5, True)
    
  • Tuples

    Tuple is one of the built-in data types in Python. A Python tuple is a sequence of comma separated items, enclosed in parentheses (). The items in a Python tuple need not be of same data type.

    Following are some examples of Python tuples −

    tup1 =("Rohan","Physics",21,69.75)
    tup2 =(1,2,3,4,5)
    tup3 =("a","b","c","d")
    tup4 =(25.50,True,-55,1+2j)

    The empty tuple is written as two parentheses containing nothing −

    tup1 =();

    To write a tuple containing a single value you have to include a comma, even though there is only one value −

    tup1 =(50,);

    Following are the points to be noted −

    • In Python, tuple is a sequence data type. It is an ordered collection of items. Each item in the tuple has a unique position index, starting from 0.
    • In C/C++/Java array, the array elements must be of same type. On the other hand, Python tuple may have objects of different data types.
    • Python tuple and list both are sequences. One major difference between the two is, Python list is mutable, whereas tuple is immutable. Although any item from the tuple can be accessed using its index, and cannot be modified, removed or added.

    Accessing Values in Tuples

    To access values in tuple, use the square brackets for slicing along with the index or indices to obtain value available at that index. For example −

    tup1 =('physics','chemistry',1997,2000);
    tup2 =(1,2,3,4,5,6,7);print("tup1[0]: ", tup1[0]);print("tup2[1:5]: ", tup2[1:5]);

    When the above code is executed, it produces the following result −

    tup1[0]:  physics
    tup2[1:5]:  [2, 3, 4, 5]

    Updating Tuples

    Tuples are immutable which means you cannot update or change the values of tuple elements. You are able to take portions of existing tuples to create new tuples as the following example demonstrates −

    tup1 =(12,34.56);
    tup2 =('abc','xyz');# Following action is not valid for tuples# tup1[0] = 100;# So let's create a new tuple as follows
    tup3 = tup1 + tup2;print(tup3);

    When the above code is executed, it produces the following result −

    (12, 34.56, 'abc', 'xyz')
    

    Delete Tuple Elements

    Removing individual tuple elements is not possible. There is, of course, nothing wrong with putting together another tuple with the undesired elements discarded.

    To explicitly remove an entire tuple, just use the del statement. For example −

    tup =('physics','chemistry',1997,2000);print(tup);del tup;print("After deleting tup : ");print(tup);

    This produces the following result. Note an exception raised, this is because after del tup tuple does not exist any more −

    ('physics', 'chemistry', 1997, 2000)
    After deleting tup :
    Traceback (most recent call last):
       File "test.py", line 9, in <module>
    
      print (tup);
    NameError: name 'tup' is not defined

    Python Tuple Operations

    In Python, Tuple is a sequence. Hence, we can concatenate two tuples with + operator and concatenate multiple copies of a tuple with “*” operator. The membership operators “in” and “not in” work with tuple object.

    Python ExpressionResultsDescription
    (1, 2, 3) + (4, 5, 6)(1, 2, 3, 4, 5, 6)Concatenation
    (‘Hi!’,) * 4(‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’)Repetition
    3 in (1, 2, 3)TrueMembership

    Even if there is only one object in a tuple, you must give a comma after it. Otherwise, it is treated as a string.

    Indexing, Slicing, and Matrixes

    Because tuples are sequences, indexing and slicing work the same way for tuples as they do for strings. Assuming following input −

    L =('spam','Spam','SPAM!')
    Python ExpressionResultsDescription
    L[2]‘SPAM!’Offsets start at zero
    L[-2]‘Spam’Negative: count from the right
    L[1:][‘Spam’, ‘SPAM!’]Slicing fetches sections

    No Enclosing Delimiters

    Any set of multiple objects, comma-separated, written without identifying symbols, i.e., brackets for lists, parentheses for tuples, etc., default to tuples, as indicated in these short examples −

    print('abc',-4.24e93,18+6.6j,'xyz');
    x, y =1,2;print("Value of x , y : ", x,y);

    When the above code is executed, it produces the following result −

    abc -4.24e+93 (18+6.6j) xyz
    Value of x , y : 1 2
    

    Built-in Functions with Tuples

    Following are the built-in functions we can use with tuples −

    Sr.No.Function with Description
    1cmp(tuple1, tuple2)Compares elements of both tuples.
    2len(tuple)Gives the total length of the tuple.
    3max(tuple)Returns item from the tuple with max value.
    4min(tuple)Returns item from the tuple with min value.
    5tuple(seq)Converts a list into tuple.
  • List Exercises

    Python List Exercise 1

    Python program to find unique numbers in a given list.

    L1 =[1,9,1,6,3,4,5,1,1,2,5,6,7,8,9,2]
    L2 =[]for x in L1:if x notin L2:
    
      L2.append(x)print(L2)</pre>

    It will produce the following output −

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

    Python List Exercise 2
    Python program to find sum of all numbers in a list.

    L1 = [1, 9, 1, 6, 3, 4]
    ttl = 0
    for x in L1:
    ttl+=x
    print ("Sum of all numbers Using loop:", ttl)
    ttl = sum(L1)
    print ("Sum of all numbers sum() function:", ttl)
    It will produce the following output −

    Sum of all numbers Using loop: 24
    Sum of all numbers sum() function: 24
    Python List Exercise 3
    Python program to create a list of 5 random integers.

    import random
    L1 = []
    for i in range(5):
    x = random.randint(0, 100)
    L1.append(x)
    print (L1)
    It will produce the following output −

    [77, 3, 20, 91, 85]
  • List Methods

    List is one of the fundamental data structures in Python, It provides a flexible way to store and manage a collection of items. It has several built-in methods that allow you to add, update, and delete items efficiently.

    Lists in Python can contain items of different data types, including other lists, making them highly flexible to different scenarios. The list object includes several built-in methods that allow you to add, update, and delete items efficiently, as well as to perform various operations on the list’s elements.

    Python List Methods

    The list methods enable you to manipulate lists easily and effectively, whether you are appending new items, removing existing ones, or even sorting and reversing the list. By using these built-in methods, you can work with lists in Python more effectively, allowing you to write more efficient and readable code.

    Printing All the List Methods

    To view all the available methods for lists, you can use the Python dir() function, which returns all the properties and functions related to an object. Additionally, you can use the Python help() function to get more detailed information about each method. For example:

    print(dir([]))print(help([].append))

    The above code snippet provides a complete list of properties and functions related to the list class. It also demonstrates how to access detailed documentation for a specific method in your Python environment. Here is the output −

    ['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    Help on built-in function append:
    
    append(object, /) method of builtins.list instance
    
    Append object to the end of the list.
    (END)

    Below, the built-in methods for lists in Python, which are categorized based on their functionality. Let’s explore and understand the basic fuctionality of each method.

    Methods to Add Elements to a List

    The following are the methods specifically designed for adding new item/items into a list −

    Sr.No.Methods with Description
    1list.append(obj)Appends object obj to list.
    2list.extend(seq)Appends the contents of seq to list
    3list.insert(index, obj)Inserts object obj into list at offset index

    Methods to Remove Elements from a List

    The following are the methods specifically designed for removing items from a list −

    Sr.No.Methods with Description
    1list.clear()Clears all the contents of the list.
    2list.pop(obj=list[-1])Removes and returns the last object or the object at the specified index from the list.
    3list.remove(obj)Removes the first occurrence of object obj from the list.

    Methods to Access Elements in a List

    These are the methods used for finding or counting items in a list −

    Sr.No.Methods with Description
    1list.index(obj)Returns the lowest index in list that obj appears
    2list.count(obj)Returns count of how many times obj occurs in the list.

    Copying and Ordering Methods

    These are the methods used for creating copies and arranging items in a list −

    Sr.No.Methods with Description
    1list.copy()Returns a copy of the list object.
    2list.sort([func])Sorts the objects in the list in place, using a comparison function if provided.
    3list.reverse()Reverses the order of objects in the list in place.
  •  Join Lists

    Join Lists in Python

    Joining lists in Python refers to combining the elements of multiple lists into a single list. This can be achieved using various methods, such as concatenation, list comprehension, or using built-in functions like extend() or + operator.

    Joining lists does not modify the original lists but creates a new list containing the combined elements.

    Join Lists Using Concatenation Operator

    The concatenation operator in Python, denoted by +, is used to join two sequences, such as strings, lists, or tuples, into a single sequence. When applied to lists, the concatenation operator joins the elements of the two (or more) lists to create a new list containing all the elements from both lists.

    We can join a list using the concatenation operator by simply using the + symbol to concatenate the lists.

    Example

    In the following example, we are concatenating the elements of two lists “L1” and “L2”, creating a new list “joined_list” containing all the elements from both lists −

    # Two lists to be joined
    L1 =[10,20,30,40]
    L2 =['one','two','three','four']# Joining the lists
    joined_list = L1 + L2
    
    # Printing the joined listprint("Joined List:", joined_list)

    Following is the output of the above code −

    Joined List: [10, 20, 30, 40, 'one', 'two', 'three', 'four']
    

    Join Lists Using List Comprehension

    List comprehension is a concise way to create lists in Python. It is used to generate new lists by applying an expression to each item in an existing iterable, such as a list, tuple, or range. The syntax for list comprehension is −

    new_list =[expression for item in iterable]

    This creates a new list where expression is evaluated for each item in the iterable.

    We can join a list using list comprehension by iterating over multiple lists and appending their elements to a new list.

    Example

    In this example, we are joining two lists, L1 and L2, into a single list using list comprehension. The resulting list, joined_list, contains all elements from both L1 and L2 −

    # Two lists to be joined
    L1 =[36,24,3]
    L2 =[84,5,81]# Joining the lists using list comprehension
    joined_list =[item for sublist in[L1, L2]for item in sublist]# Printing the joined listprint("Joined List:", joined_list)

    Output of the above code is as follows −

    Joined List: [36, 24, 3, 84, 5, 81]
    

    Join Lists Using append() Function

    The append() function in Python is used to add a single element to the end of a list. This function modifies the original list by adding the element to the end of the list.

    We can join a list using the append() function by iterating over the elements of one list and appending each element to another list.

    Example

    In the example below, we are appending elements from “list2” to “list1” using the append() function. We achieve this by iterating over “list2” and adding each element to “list1” −

    # List to which elements will be appended
    list1 =['Fruit','Number','Animal']# List from which elements will be appended
    list2 =['Apple',5,'Dog']# Joining the lists using the append() functionfor element in list2:
    
    list1.append(element)# Printing the joined listprint("Joined List:", list1)</pre>

    We get the output as shown below −

    Joined List: ['Fruit', 'Number', 'Animal', 'Apple', 5, 'Dog']
    

    Join Lists Using extend() Function

    The Python extend() function is used to append elements from an iterable (such as another list) to the end of the list. This function modifies the original list in place, adding the elements of the iterable to the end of the list.

    We can join a list using the extend() function by calling it on one list and passing another list (or any iterable) as an argument. This will append all the elements from the second list to the end of the first list.

    Example

    In the following example, we are extending "list1" by appending the elements of "list2" using the extend() function −

    # List to be extended
    list1 =[10,15,20]# List to be added
    list2 =[25,30,35]# Joining the lists using the extend() function
    list1.extend(list2)# Printing the extended listprint("Extended List:", list1)

    The output obtained is as shown below −

    Extended List: [10, 15, 20, 25, 30, 35]
    
  • Copy Lists

    Copying a List in Python

    Copying a list in Python refers to creating a new list that contains the same elements as the original list. There are different methods for copying a list, including, using slice notation, the list() function, and using the copy() method.

    Each method behaves differently in terms of whether it creates a shallow copy or a deep copy. Let us discuss about all of these deeply in this tutorial.

    Shallow Copy on a Python List

    A shallow copy in Python creates a new object, but instead of copying the elements recursively, it copies only the references to the original elements. This means that the new object is a separate entity from the original one, but if the elements themselves are mutable, changes made to those elements in the new object will affect the original object as well.

    Example of Shallow Copy

    Let us illustrate this with the following example −

    Open Compiler

    import copy
    # Original list
    original_list =[[1,2,3],[4,5,6],[7,8,9]]# Creating a shallow copy
    shallow_copied_list = copy.copy(original_list)# Modifying an element in the shallow copied list
    shallow_copied_list[0][0]=100# Printing both listsprint("Original List:", original_list)print("Shallow Copied List:", shallow_copied_list)

    As you can see, even though we only modified the first element of the first sublist in the shallow copied list, the same change is reflected in the original list as well.

    This is because a shallow copy only creates new references to the original objects, rather than creating copies of the objects themselves −

    Original List: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
    Shallow Copied List: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
    

    Deep Copy on a Python List

    A deep copy in Python creates a completely new object and recursively copies all the objects referenced by the original object. This means that even nested objects within the original object are duplicated, resulting in a fully independent copy where changes made to the copied object do not affect the original object, and vice versa.

    Example of Deep Copy

    Let us illustrate this with the following example −

    Open Compiler

    import copy
    # Original list
    original_list =[[1,2,3],[4,5,6],[7,8,9]]# Creating a deep copy
    deep_copied_list = copy.deepcopy(original_list)# Modifying an element in the deep copied list
    deep_copied_list[0][0]=100# Printing both listsprint("Original List:", original_list)print("Deep Copied List:", deep_copied_list)

    As you can see, when we modify the first element of the first sublist in the deep copied list, it does not affect the original list.

    This is because a deep copy creates a new object and recursively copies all the nested objects, ensuring that the copied object is fully independent from the original one −

    Original List: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    Deep Copied List: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
    

    Copying List Using Slice Notation

    Slice notation in Python allows you to create a subsequence of elements from a sequence (like a list, tuple, or string) by specifying a start index, an end index, and an optional step size. The syntax for slice notation is as follows −

    [start:end:step]

    Where, start is the index where the slice starts, end is the index where the slice ends (exclusive), and step is the step size between elements.

    We can copy a list using slice notation by specifying the entire range of indices of the original list. This effectively creates a new list with the same elements as the original list.

    Any modifications made to the copied list will not affect the original list, and vice versa, because they are separate objects in memory.

    Example

    In this example, we are creating a slice of the “original_list”, effectively copying all its elements into a new list “copied_list” −

    # Original list
    original_list =[1,2,3,4,5]# Copying the list using slice notation
    copied_list = original_list[1:4]# Modifying the copied list
    copied_list[0]=100# Printing both listsprint("Original List:", original_list)print("Copied List:", copied_list)

    We get the result as shown below −

    Original List: [1, 2, 3, 4, 5]
    Copied List: [100, 3, 4]
    

    Copying List Using the list() Function

    The list() function in Python is a built-in function used to create a new list object. It can accept an iterable (like another list, tuple, set, etc.) as an argument and create a new list containing the elements of that iterable. If no argument is provided, an empty list is created.

    We can copy a list using the list() function by passing the original list as an argument. This will create a new list object containing the same elements as the original list.

    Example

    In the example below, we are creating a new list object “copied_list” containing the same elements as “original_list” using the list() function −

    # Original list
    original_list =[1,2,3,4,5]# Copying the list using the list() constructor
    copied_list =list(original_list)# Printing both listsprint("Original List:", original_list)print("Copied List:", copied_list)

    Following is the output of the above code −

    Original List: [1, 2, 3, 4, 5]
    Copied List: [1, 2, 3, 4, 5]
    

    Copying List Using the copy() Function

    In Python, the copy() function is used to create a shallow copy of a list or other mutable objects. This function is part of the copy module in Python’s standard library.

    We can copy a list using the copy() function by invoking it on the original list. This creates a new list object that contains the same elements as the original list.

    Example

    In the following example, we are using the copy() function to creates a new list object “copied_list” containing the same elements as “original_list” −

    import copy
    original_list =[1,2,3,4,5]# Copying the list using the copy() function
    copied_list = copy.copy(original_list)print("Copied List:", copied_list)

    Output of the above code is as shown below −

    Copied List: [1, 2, 3, 4, 5]
  •  Sort Lists

    Sorting Lists in Python

    Sorting a list in Python is a way to arrange the elements of the list in either ascending or descending order based on a defined criterion, such as numerical or lexicographical order.

    This can be achieved using the built-in sorted() function or by calling the sort() method on the list itself, both of which modify the original list or return a new sorted list depending on the method used.

    Sorting Lists Using sort() Method

    The python sort() method is used to sort the elements of a list in place. This means that it modifies the original list and does not return a new list.

    Syntax

    The syntax for using the sort() method is as follows −

    list_name.sort(key=None, reverse=False)

    Where,

    • list_name is the name of the list to be sorted.
    • key (optional) is a function that defines the sorting criterion. If provided, it is applied to each element of the list for sorting. Default is None.
    • reverse (optional) is a boolean value. If True, the list will be sorted in descending order. If False (default), the list will be sorted in ascending order.

    Example of Sorting List in Lexicographical Order

    In the following example, we are using the sort() function to sort the items of the list alphanumerically −

    list1 =['physics','Biology','chemistry','maths']print("list before sort:", list1)
    list1.sort()print("list after sort : ", list1)

    It will produce the following output −

    list before sort: ['physics', 'Biology', 'chemistry', 'maths']
    list after sort :  ['Biology', 'chemistry', 'maths', 'physics']
    

    Example of Sorting List in Numerical Order

    In here, we are using the sort() function to sort the given list in numerical order −

    list2 =[10,16,9,24,5]print("list before sort", list2)
    list2.sort()print("list after sort : ", list2)

    The output produced is as shown below −

    list before sort [10, 16, 9, 24, 5]
    list after sort :  [5, 9, 10, 16, 24]
    

    Sorting Lists Using sorted() Method

    The sorted() function in Python is a built-in function used to sort the elements of an iterable (such as a list, tuple, or string) and returns a new sorted list, leaving the original iterable unchanged.

    Syntax

    The syntax for using the sorted() method is as follows −

    sorted(iterable, key=None, reverse=False)

    Where,

    • iterable is the iterable (e.g., list, tuple, string) whose elements are to be sorted.
    • key (optional) is a function that defines the sorting criterion. If provided, it is applied to each element of the iterable for sorting. Default is None.
    • reverse (optional) is a boolean value. If True, the iterable will be sorted in descending order. If False (default), the iterable will be sorted in ascending order.

    Example

    In the following example, we are using the sorted() function to sort a list of numbers and retrieve a new sorted list −

    numbers =[3,1,4,1,5,9,2,6,5,3,5]# Sorting in descending order
    sorted_numbers_desc =sorted(numbers, reverse=True)print(sorted_numbers_desc)

    Following is the output of the above code −

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

    Sorting List Items with Callback Function

    In Python, a callback function refers to a function that is passed as an argument to another function and is invoked or called within that function

    We can sort list items with a callback function by using the sorted() function or sort() function in Python. Both of these functions allows us to specify a custom sorting criterion using the “key” parameter, which accepts a callback function. This callback function defines how the elements should be compared and sorted.

    Example Using str.lower() as key Parameter

    The str.lower() method in Python is used to convert all the characters in a string to lowercase. It returns a new string with all alphabetic characters converted to lowercase while leaving non-alphabetic characters unchanged.

    In this example, we are passing the str.lower() method as an argument to the “key” parameter within the sort() function −

    list1 =['Physics','biology','Biomechanics','psychology']print("list before sort", list1)
    list1.sort(key=str.lower)print("list after sort : ", list1)

    It will produce the following output −

    list before sort ['Physics', 'biology', 'Biomechanics', 'psychology']
    list after sort : ['biology', 'Biomechanics', 'Physics', 'psychology']
    

    Example Using user-defined Function as key Parameter

    We can also use a user-defined function as the key parameter in sort() method.

    In this example, the myfunction() uses % operator to return the remainder, based on which the sorting is performed −

    defmyfunction(x):return x%10
    list1 =[17,23,46,51,90]print("list before sort", list1)
    list1.sort(key=myfunction)print("list after sort : ", list1)

    It will produce the following output −

    list before sort [17, 23, 46, 51, 90]
    list after sort: [90, 51, 23, 46, 17]
  • List Comprehension

    List Comprehension in Python

    list comprehension is a concise way to create lists. It is similar to set builder notation in mathematics. It is used to define a list based on an existing iterable object, such as a list, tuple, or string, and apply an expression to each element in the iterable.

    Syntax of Python List Comprehension

    The basic syntax of list comprehension is −

    new_list =[expression for item in iterable if condition]

    Where,

    • expression is the operation or transformation to apply to each item in the iterable.
    • item is the variable representing each element in the iterable.
    • iterable is the sequence of elements to iterate over.
    • condition (optional) is an expression that filters elements based on a specified condition.

    Example of Python List Comprehension

    Suppose we want to convert all the letters in the string “hello world” to their upper-case form. Using list comprehension, we iterate through each character, check if it is a letter, and if so, convert it to uppercase, resulting in a list of uppercase letters −

    string ="hello world"
    uppercase_letters =[char.upper()for char in string if char.isalpha()]print(uppercase_letters)

    The result obtained is displayed as follows −

    ['H', 'E', 'L', 'L', 'O', 'W', 'O', 'R', 'L', 'D']
    

    List Comprehensions and Lambda

    In Python, lambda is a keyword used to create anonymous functions. An anonymous function is a function defined without a name. These functions are created using the lambda keyword followed by a comma-separated list of arguments, followed by a colon :, and then the expression to be evaluated.

    We can use list comprehension with lambda by applying the lambda function to each element of an iterable within the comprehension, generating a new list.

    Example

    In the following example, we are using list comprehension with a lambda function to double each element in a given list “original_list”. We iterate over each element in the “original_list” and apply the lambda function to double it −

    Open Compiler

    original_list =[1,2,3,4,5]
    doubled_list =[(lambda x: x *2)(x)for x in original_list]print(doubled_list)

    Following is the output of the above code −

    [2, 4, 6, 8, 10]
    

    Nested Loops in Python List Comprehension

    A nested loop in Python is a loop inside another loop, where the inner loop is executed multiple times for each iteration of the outer loop.

    We can use nested loops in list comprehension by placing one loop inside another, allowing for concise creation of lists from multiple iterations.

    Example

    In this example, all combinations of items from two lists in the form of a tuple are added in a third list object −

    Open Compiler

    list1=[1,2,3]
    list2=[4,5,6]
    CombLst=[(x,y)for x in list1 for y in list2]print(CombLst)

    It will produce the following output −

    [(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
    

    Conditionals in Python List Comprehension

    Conditionals in Python refer to the use of statements like “if”, “elif”, and “else” to control the flow of a code based on certain conditions. They allow you to execute different blocks of code depending on whether a condition evaluates to “True” or “False”.

    We can use conditionals in list comprehension by including them after the iterable and before the loop, which filters elements from the iterable based on the specified condition while generating the list.

    Example

    The following example uses conditionals within a list comprehension to generate a list of even numbers from 1 to 20 −

    Open Compiler

    list1=[x for x inrange(1,21)if x%2==0]print(list1)

    We get the output as follows −

    [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
    

    List Comprehensions vs For Loop

    List comprehensions and for loops are both used for iteration, but they differ in terms of syntax and usage.

    List comprehensions are like shortcuts for creating lists in Python. They let you generate a new list by applying an operation to each item in an existing list.

    For loop, on the other hand, is a control flow statement used to iterate over elements of an iterable one by one, executing a block of code for each element.

    List comprehensions are often preferred for simpler operations, while for loops offer more flexibility for complex tasks.

    Example Using For Loop

    Suppose we want to separate each letter in a string and put all non-vowel letters in a list object. We can do it by a for loop as shown below −

    chars=[]for ch in'TutorialsPoint':if ch notin'aeiou':
    
      chars.append(ch)print(chars)</pre>

    The chars list object is displayed as follows −

    ['T', 't', 'r', 'l', 's', 'P', 'n', 't']
    

    Example Using List Comprehension

    We can easily get the same result by a list comprehension technique. A general usage of list comprehension is as follows −

    listObj =[x for x in iterable]

    Applying this, chars list can be constructed by the following statement −

    chars =[ char for char in'TutorialsPoint'if char notin'aeiou']print(chars)

    The chars list will be displayed as before −

    ['T', 't', 'r', 'l', 's', 'P', 'n', 't']
    

    Example

    The following example uses list comprehension to build a list of squares of numbers between 1 to 10 −

    squares =[x*x for x inrange(1,11)]print(squares)

    The squares list object is −

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    

    Advantages of List Comprehension

    Following are the advantages of using list comprehension −

    • Conciseness − List comprehensions are more concise and readable compared to traditional for loops, allowing you to create lists with less code.
    • Efficiency − List comprehensions are generally faster and more efficient than for loops because they are optimized internally by Python's interpreter.
    • Clarity − List comprehensions result in clearer and more expressive code, making it easier to understand the purpose and logic of the operation being performed.
    • Reduced Chance of Errors − Since list comprehensions are more compact, there is less chance of errors compared to traditional for loops, reducing the likelihood of bugs in your code.