Sunday, April 27, 2025

Lists

 


        Lists Data Type

        List is a compound data type used to store data items as a ordered collection. The data items may be of single data type (int/float/str/etc.) or multiple data types which includes int, float, str, another list, etc. It is a widely used data structure for arranging and  accessing data items in many different ways (eg. stack, queue, heirarchical structures). Unlike strings, they can be modified after the creation and hence referred as mutable data type. Most of the time they are used as a data structure with data items of a single data type. Some examples of lists are as follows 

list1 = ['apple', 'carrot', 'mint']     # list of strings

list2 = [45,56,43]                                               # list of integers

lt3 =       ['apple', 45, True, 56.56]                # list with different data type elements

lt4 =       [list1, list3]                                          # list of lists

lt5 =       [[1,2,3],[4,5,6,7,8]]                          # list of unnamed lists

operations on lists  

1.       Indexing (accessing an element of the list)

 Any element of the list can be accessed using indexing. The first item of the list is at index zero, the second element at index 1, and so on (referred as forward indexing). There is also another way of indexing: backward indexing. The last item is referred using the index -1, last but one with -2 and so on.

        Forward Indexing:  The following code snippet shows the creation of the list named as PLs_list and then accessing its elements using indexing to print on the terminal. 

PLs_list = ['C', 'C++', 'Java', 'Python']

print(PLs_list[0])                  # Output: C     ; accessed first element

print(PLs_list[3])                  # Output: Python         ; accessed last element

The first item ('C') is accessed using index 0, and fourth item  ('Python') is accessed using index 3.

 Backward Indexing: Python also supports backward (negative) indexing, which allows you to access elements from the end of the list. The last element is at index -1, the second-to-last at -2, and so forth.

PLs_list = ['C', 'C++', 'Java', 'Python']

print(PLs_list[-1])              # Output: Python       ; accessed the last element

print(PLs_list[-2])              # Output: Java                  ; accessed second element from right

print(PLs_list[-4])              # Output: C   ; accessed the first element

It is a very convenient way to access end of the list elements without knowing its length.

2. Slices (accessing more than one element of a list)

       Slicing is used to extract a sublist (a portion of the list) from the list. The syntax of slice is list_name[start:stop:step] where start indicates from which index to start extraction, stop indicates where to stop (stop-1) and step is used to indicate the increment between elements. The default value of the step is 1.    

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

print(a_list[2:5])    # Output: [2, 3, 4] (elements from index 2 up to but not including 5)

print(a_list[:4])     # Output: [0, 1, 2, 3] (elements from the beginning up to but not including 4)

print(a_list[6:])     # Output: [6, 7, 8, 9] (elements from index 6 to the end)

print(a_list[1:8:2])  # Output: [1, 3, 5, 7] (elements from index 1 to 8 with a step of 2)

print(a_list[:])      # Output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (a copy of the entire list)

print(a_list[::-1])   # Output: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (reversing the list)

print(a_list[-1:-5:-1]) # output: [9, 8, 7, 6] (excldes -5)

Slicing is a powerful way to work with subsets of lists.

 3. Mutability

        This property allows you to change the elements of the list after creation. Use indexing to modify a single item or slice to modify a sublist of the list.

PLs_list = ['C', 'C++', 'Java', 'Python']

PLs_list[0] = 'Go'                                    #changing the element at index 0

PLs_list[2] ='Oracle Java'                      # changing the element at index 2

print(PLs_list)                                    # ouput: ['Go','C++', "Oracle Java', 'Pyhton']


numbers = [10, 20, 30, 40, 50, 60]

numbers[1:3] = [200, 300]            # Changing a slice of elements; index 1 and 2

print(numbers)                                 # Output: [10, 200, 300, 40, 50, 60]

 This mutability allows for dynamic modification of list contents as illustrated using the code snippet. Read the code with comments to understand the output.

 4. Concatenation

        The operator + is used to concatenate two lists to create a unified list. Any number of lists can be concatenated to create a combined new list.

 PLs_list1 = ['C', 'C++', 'Java']

PLs_list2 = ['R', 'Python', "Julia']

PLs_combined_list = PLs_list1 + PLs_list2

print(PLs_combined_list)             # Output: ['C', 'C++', 'Java','R', 'Python', "Julia']

 Concatenation creates a new list containing all the elements from the original lists in the order they appear as illustrated in the code listing above. 

        5. Replication

        The * operator is used as replication operator. It repeats the original list specified number of times to create a new list.

PLs_list = ['Python']

PLs_repeated_list = PLs_list * 3

print(PLs_repeated_list)                                              # Output: ['Python', 'Python', 'Python']

numbers = [0.98, 1.56]

rpt_numbers = numbers * 2

print(rpt_numbers)                                                        # Output: [0.98,1.56,0.98,1.56]

Replication is useful for quickly creating lists with repeated elements or patterns.

 6. `del` Statement for Lists

        The del statement can be used to delete a particular item of the list by specifing its index. It is also possible to delete the entire list or sublist. The following code snippet illustrates the same.

PLs_list = ['C', 'C++', 'Java','R', 'Python', "Julia']

del PLs_list[1]       # Deleting the element at index 1

print(PLs_list)       # Output: ['C', 'Java','R', 'Python', "Julia']

del PLs_list[1:3]    # Deleting a slice of elements

print(PLs_list)       # Output: ['C', 'Python', 'Julia']

num_list = [10, 20, 30]

del num_list    # Deleting the entire list

print(num_list) # Trying to access num_list here would result in a NameError

 The      del       statement permanently removes elements or the list itself from memory.

 7. Growing Lists

        Lists can be grown dynamically after their creation. Common methods for adding elements include      append()       (adds an element to the end),      insert()       (inserts an element at a specific index), and      extend()       (adds multiple elements from another iterable to the end).

my_list = ['apple', 'banana']

my_list.append('orange')

print(my_list)       # Output: ['apple', 'banana', 'orange']

my_list.insert(1, 'grape')

print(my_list)       # Output: ['apple', 'grape', 'banana', 'orange']

another_list = ['kiwi', 'mango']

my_list.extend(another_list)

print(my_list)       # Output: ['apple', 'grape', 'banana', 'orange', 'kiwi', 'mango']

These methods provide flexible ways to add elements to existing lists.

  8. `for` Loop with Lists

        The `for` loop is commonly used to iterate over the elements of a list, allowing you to perform an action on each item.

PLs_list = ['Java','Python']

for PL in PLs_list:

                print(PL, " is a powerful PL")

This loop will iterate through each string in the `fruits` list and print a message.

   9. `in` and `not in` Operators with Lists

        The in operator is used to verify that a specific item exists in the list. Whereas not in operator is used to verify a particular item is not present in the list. The result is True or False depending on the presence or absence of the specified element in the list. The following code snippet illustrates the same.  

PLs_list = ['C', 'C++', 'Java', 'Python',]

print('C++' in PLs_list)    # Output: True

print('R' in PLs_list)     # Output: False

print('Matlab' not in PLs_list) # Output: True

print('Python' not in PLs_list)  # Output: False

The in and not in operators are useful for checking membership in a list.

10. Multiple Assignment

        Python supports multiple variables assignment using the same assignment operator =. The condition is left side variables and right values for assignment must be in same number. The same is illustrated in the following code example.

PLs_list = ['C', 'Java', 'Python']

embedded, banking, data_science = PLs_list

print(embedded, banking, data_science) # Output: C Java Python

Multiple assignment provides a concise way to unpack elements from a list into individual variables.

  

Common List Functions

 List is an object, and it comes with several built-in functions (or methods) that allow you to manipulate and interact with the list's contents. Some of the commonly used functions of list include index(), insert(), append(), sort, and many more. Some of them are illustrated in the following lines.

         1. index()

        The      index()       function is used to find the index of the first occurrence of a specified value in the list.

         The function can be directed to search from the specified starting point (index).  

PLs_list = ['C', 'C++', 'Java','Python', 'C++']

index_C++ = PLs_list.index('C++')                            # index of C++

print(index_C++)                                             # output: 1

 index_C++ = PLs_list.index('C++',2)                         # search index for 'C++' starting from index 2

print(index_C++)                                             # output: 4

 # erroneous code

index = PLs_list.index('Matlab')                 # search index for the value 'Matlab'

print(index)                                        # output: ValueError

          

 If the specified value is not found in the list, a      ValueError       will be raised. 

    2. append()

        The append() function adds a single element to the end of the list. It is helpful to grow the list dynamically       

PLs_list = ['C', 'C++', 'Java','Python']

PLs_list.append('R')                        # 'R' is added to end of the list

print(PLs_list)                                    # output: ['C', 'C++', 'Java','Python','R']                  

    The append() method modifies the original list directly.

  3. insert()

        The insert() function inserts an element at a specified index in the list. It takes two arguments: the index where the element should be inserted and the element itself. This function is also helpful to grow the list dynamically

numbers = [1, 3, 4]

numbers.insert('R', 2)

print(numbers) # Output: Numbers after insert: [1, 2, 'R', 4]

When you insert an element, the existing elements from that index onwards are shifted to the right.

4. remove()

        The      remove()       function removes the first occurrence of a specified value from the list.

 numbers = [100, 200, 300, 200, 400]

numbers.remove(200)

print(numbers) # Output: Numbers after remove: [100, 300, 200, 400]

print(numbers.remove(600))                     # results in ValueError (The element 600 not present in the list)

 Similar to      index()      , if the specified value is not found, a      ValueError       will be raised.

 5. sort()

 The      sort()       function sorts the elements of the list in place (modifies the original list). By default, it sorts in ascending order.

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

numbers.sort()

print(numbers)    # Output: [1, 1, 2, 3, 4, 5, 6, 9]

 PLs_list = ['C', 'R', 'Java', 'C++', 'Python']

PLs_list.sort()      # sorted according to ASCII values of A-Z

print(PLs_list)                                    # output: ['C', 'C++', 'Java','Python','R']

PLs_list = ['C', 'R', 'java', 'C++', 'python']                 # lowercase j and p

PLs_list.sort()    # lower case alphabets value higher compared to upper case

print(PLs_list)                                    # output: ['C', 'C++', 'R','java','python']

  The sort() method modifies the list directly and returns None.

  6. sort() in Reverse Order

        To sort a list in descending order, you can pass the reverse=True argument to the sort() function. The default value of reverse argument is False.

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

numbers.sort(reverse=True)

print(numbers)                                 # output: [90, 60, 50, 40, 30, 20, 10, 10]

PLs_list = ['C', 'R', 'Java', 'C++', 'Python']

PLs_list.sort(reverse=True)           # sorted according to ASCII values of A-Z

print(PLs_list)                                    # output: ['R', 'Python', 'Java', 'C++, 'C']

PLs_list = ['C', 'R', 'java', 'C++', 'python']                 # lowercase j and p

PLs_list.sort()    # lower case alphabets value higher compared to upper case

print(PLs_list)                                    # output: ['python', 'java', 'R', 'C++', 'C']

 This is a simple way to get a descending sorted list. Note that the default sort for strings is case-sensitive. If you need a case-insensitive sort, you can use the key argument with str.lower: my_list.sort(key=str.lower)

           Functions with list as an argument

         Some of the Python functions that take lists as arguments, enabling powerful operations and manipulations: 

         1. len()

         The      len()       function returns the number of items in a list. 

 a_list = [10, 20, 30, 40, 50,60]

 list_length = len(a_list)

 print(list_length)  # Output: 6

2. max()       

          The      max()       function returns the largest item in a list. 

numbers = [5, 10, 3, 18, 1,90]

max_value = max(numbers)

print("The maximum value is: ", max_value)  # Output: The maximum value is: 90

  3. min()     

          The      min()       function returns the smallest item in a list. 

numbers = [10, 20, 5, 15, 30, -60]

min_value = min(numbers)

print("The minimum value is: ", min_value)  # Output: The minimum value is: -60

 4. sum()     

          The      sum()       function returns the sum of all elements in a list. 

 numbers = [10, 20, 30, 40, -20]

 total = sum(numbers)

 print("The sum of the numbers is: ", total)  # Output: The sum of the numbers is: 80

  5. sorted()     

  The      sorted()       function returns a new sorted list from the items in iterable. 

numbers = [6, 9, 3, 1, -45]

sorted_numbers = sorted(numbers)

print("Sorted list: ", sorted_numbers)  # Output: Sorted list: [-45, 1, 3, 6, 9]

 6. list()     

          The      list()       function converts an iterable (like a tuple) to a list. 

a_tuple = ('C', 'C++', 'Java')

a_list = list(a_tuple)

print("Converted list: ", a_list)  # Output: Converted list: ['C', 'C++', 'Java']

 7. any()       

         The      any()       function returns      True       if any element of the iterable is true. 

list1 = [True, False, False]

result = any(list1)

print("Any is True: " , result)  # Output: Any is True: True

 8. all()       

          The      all()       function returns      True       if all elements of the iterable are true. 

list1 = [True, True, True]

result = all(list1)

print("All are True: ", result)  # Output: All are True: True

 9. enumerate()     

          The      enumerate()       function adds a counter to an iterable and returns it as an enumerate object. 

a_list = ['C', 'C++', 'Java']

for index, PL in enumerate(a_list):

     print("Index ", index, PL}")

                     # Output:

                     # Index 0 'C'

                     # Index 1 'C++'

                     # Index 2 'Java'

   10. zip()       

           The      zip()       function aggregates elements from each of the iterables. 

names = ['John', 'Peter', 'Steve']

ages = [45, 54, 33]

for name, age in zip(names, ages):

    print(f"{name} is {age} years old.")

                     # Output:

                     # John is 45 years old.

                     # Peter is 54 years old.

                     # Steve is 33 years old.

    11. reversed()     

          The      reversed()       function returns a reverse iterator. 

a_list = [1, 2, 3, 4, 5,6]

reversed_list = list(reversed(a_list))

print("Reversed list: ", reversed_list)  # Output: Reversed list: [6, 5, 4, 3, 2, 1]

 12. copy.copy()     

copy.copy()       creates a shallow copy of a list. 

import copy

original_list = [10, 20, [30, 40]]

copied_list = copy.copy(original_list)

copied_list[2][0] = 900

print("Original list: ", original_list)  # Output: Original list: [10, 20, [900, 40]]

print(f"Copied list: {copied_list}")      # Output: Copied list: [10, 20, [900, 40]]

13. copy.deepcopy()     

copy.deepcopy()       creates a deep copy of a list. Use deepcopy() to copy nested lists. 

import copy

original_list = [10, 20, [30, 40]]

copied_list = copy.copy(original_list)

copied_list[2][0] = 900

print("Original list: ", original_list)  # Output: Original list: [10, 20, [30, 40]]

print("Copied list: ", copied_list)      # Output: Copied list: [10, 20, [900, 40]]

Passing Lists as Arguments to Functions (Pass by reference)     

         In Python, you can pass lists as arguments to functions, just like any other data type. When you pass a list to a function, the function receives a reference to the original list. This means that if the function modifies the list, those changes will be reflected in the original list outside the function. 

 Modifying a List Inside a Function     

 def add_element(data_list, element):

     """Adds an element to the end of a given list."""

     data_list.append(element)

     print(f"List inside function: {data_list}")

     my_numbers = [10, 20, 30]

     add_element(my_numbers, 40)

     print(f"List outside function: {my_numbers}")

                    # Output:

                    # List inside function: [10, 20, 30, 40]

                    # List outside function: [10, 20, 30, 40]

         As you can see, the      append()       operation inside the      add_element       function directly modifies the      my_numbers       list that was passed as an argument. 

 Creating a New List Inside a Function (local list) 

  def square_num(number_list):

      """Creates a new list containing the squares of numbers in the input list."""

      squared_list = []

      for number in number_list:

          squared_list.append(number ** 2)

          return squared_list

 original_numbers = [10, 20, 30, 40]

 squares = square_num(original_numbers)

 print(f"Original list: {original_numbers}")

 print(f"Squared list: {squares}")

                    # Output:

                    # Original list: [10, 20, 30, 40]

                    # Squared list: [100, 400, 900, 1600]

    In this case, the function creates and returns a new list without altering the original list passed as an argument. 

              Tuples     

      Tuples: The Essentials     

         Tuples are another fundamental sequence data type in Python, similar to lists. But, unlike strings they are immutable. Here are the key characteristics: 

Creation: Tuples are created by placing comma-separated values inside parentheses      ()      . However, even a single-item tuple requires a trailing comma. 

a_tuple = (1, 2, 3)

single_item_tuple = (5,)

empty_tuple = ()

print(a_tuple)

print(single_item_tuple)

print(empty_tuple) 

              Immutability: The most significant difference from lists is that tuples are immutable. Once a tuple is created, you cannot change its elements (add, remove, or modify). 

a_tuple = (1, 2, 3)

# The following would raise a TypeError:

                    # a_tuple[0] = 10

                    # del a_tuple[1]

                    # a_tuple.append(4)

   Indexing and Slicing:     

         Like lists, tuples support zero-based indexing and slicing to access elements or sub-sequences. 

  a_tuple = ('C', 'C++', 'Java')

  print(a_tuple[0])   # Output: C

  print(a_tuple[1:3]) # Output: ('C','C++')

  print(a_tuple[-1])  # Output: 'Java;

Concatenation and Replication:  Tuples support concatenation using the      +       operator and replication using the      *       operator, similar to lists. These operations create new tuples. 

tuple1 = (10, 20)

tuple2 = ('aa', 'bb')

combined_tuple = tuple1 + tuple2

print(combined_tuple)  # Output: (10, 20, 'aa', 'bb')

repeated_tuple = tuple1 * 3

print(repeated_tuple)  # Output: (10, 20, 10, 20, 10, 20)

 in and not in Operators : You can use the      in       and      not in       operators to check for the presence of an element in a tuple, just like with lists.

a_tuple = ('C', 'C++', 'Java')

print('C' in a_tuple)    # Output: True

print('Python' not in a_tuple) # Output: True

 Comparing Tuples and Lists :   

          the key differences between tuples and lists: 

       

          Feature                                     List                                               Tuple             

Mutability        Mutable (can be changed after creation)                Immutable 

Syntax              Created using square brackets      []                      Created using parentheses      ()      

Use Cases        Collections of items that might need to be modified    representing fixed records) Methods           append(),insert(), remove(), sort()                        count(), index() 

         Choosing between lists and tuples depends on whether you need a mutable or an immutable sequence of items. 

          

 

   

     

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

No comments:

Post a Comment