Common Data Structures

Common Data Structures

Data structures are the basic building blocks of programming. They offer distinct methods of organizing data to ensure efficient access based on your specific needs.

List

  • It is mutable, which means its elements can be modified after creation.

  • Lists can contain elements of different data types and can be accessed, modified, and iterated upon easily.

      list_value = [2,3,5,7,11]
    
      print(list_value[0]) # output = 2
      print(list_value[1]) # output = 3
      print(list_value[-1]) #output = 11
      print(list_value[-2]) #output = 7
    

    Methods

      '''Various list methods'''
    
      list_value = [0, 1, 2, 3, 4]
      list_value.append(5)
      print(list_value)  # Output: [0, 1, 2, 3, 4, 5]
    
      list_value.clear()
      print(list_value)  # Output: []
    
      list_value = [0, 1, 2, 3, 4]
      new_list = list_value.copy()
      print(new_list)  # Output: [0, 1, 2, 3, 4]
    
      list_value = [0, 1, 2, 3, 4, 1, 2, 1]
      count = list_value.count(1)
      print(count)  # Output: 3
    
      list_value.extend([5, 6, 7])
      print(list_value)  # Output: [0, 1, 2, 3, 4, 1, 2, 1, 5, 6, 7]
    
      index = list_value.index(3)
      print(index)  # Output: 3
    
      list_value.insert(2, "hello")
      print(list_value)  # Output: [0, 1, 'hello', 2, 3, 4, 1, 2, 1, 5, 6, 7]
    
      popped_element = list_value.pop(3)  # Removes and returns the element at index 3
      print(popped_element)  # Output: 2
      print(list_value)  # Output: [0, 1, 'hello', 3, 4, 1, 2, 1, 5, 6, 7]
    
      list_value.remove(1)  # Removes the first occurrence of 1
      print(list_value)  # Output: [0, 'hello', 3, 4, 1, 2, 1, 5, 6, 7]
    
      list_value.reverse()
      print(list_value)  # Output: [7, 6, 5, 1, 2, 1, 4, 3, 'hello', 0]
    
      list_value.sort()
      print(list_value)  # Output: [0, 1, 1, 2, 3, 4, 5, 6, 7]
    

    Slicing

  • Python allows you to extract a portion of a list by specifying a start index, an end index, and an optional step value.For instance, (list_name[start:end:step])

      list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
      # Basic slicing examples
      print(list[2:6])     # Output: [2, 3, 4, 5]
      print(list[:4])      # Output: [0, 1, 2, 3]
      print(list[6:])      # Output: [6, 7, 8, 9]
      print(list[1:8:2])   # Output: [1, 3, 5, 7]
    
      # Negative indices slicing examples
      print(list[-5:-2])   # Output: [5, 6, 7]
      print(list[-4:])     # Output: [6, 7, 8, 9]
      print(list[:-3])     # Output: [0, 1, 2, 3, 4, 5, 6]
    
      # Step value slicing examples
      print(list[::2])     # Output: [0, 2, 4, 6, 8]
      print(list[1:8:3])   # Output: [1, 4, 7]
    

Tuples

  • Tuples are immutable, meaning their elements cannot be modified after creation.

  • They are used to represent fixed collections of related values.

      # Creating a tuple
      my_tuple = (1, 2, 'a', 'b')
    
      # Accessing elements
      print(my_tuple[0])    # Output: 1
      print(my_tuple[2])    # Output: 'a'
    
      # Trying to modify elements (results in an error)
      my_tuple[1] = 'x'    # TypeError: 'tuple' object does not support item assignment
    

Dictionary

  • Dictionaries are associative data structures that store data as key-value pairs.

  • They provide fast and efficient access to values based on their corresponding keys.

  • Keys within a dictionary must be unique, and they are typically immutable data types, such as strings or numbers.

      # Creating a dictionary
      my_dict = {'name': 'Nirmal', 'age': 23, 'city': 'Butwal'}
    
      # Accessing elements
      print(my_dict['name'])    # Output: 'Nirmal'
      print(my_dict['age'])     # Output: 23
    
      # Modifying elements
      my_dict['age'] = 26
      print(my_dict['age'])     # Output: 26
    
      # Adding new elements
      my_dict['occupation'] = 'Engineer'
      print(my_dict) # Output: {'name': 'Nirmal', 'age': 26, 'city': 'Butwal', 'occupation': 'Engineer'}
    
      # Iterating over the dictionary
      for key, value in my_dict.items():
          print(key, ':', value)
    

Sets and Frozenset

  • Sets are unordered collections of unique elements, while frozenset is an immutable version of a set in Python.

  • Sets are used to perform mathematical set operations like union, intersection, and difference.

      set_value = {1, 2, 3, 4, 5}# Creating a set
      set_value.add(6)# Adding elements to a set
      set_value.remove(3)# Removing elements from a set
    
      # Checking membership
      print(2 in set_value)  # Output: True
    
      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
    
      print(set1.union(set2))         # Output: {1, 2, 3, 4, 5}
      print(set1.intersection(set2))  # Output: {3}
      print(set1.difference(set2))    # Output: {1, 2}
    
       '''Implementing frozenset'''
      #Set is mutable
      s = {1,2,3,4}
      s.add(5) # s = {1,2,3,4,5}
    
      #Making immutable using frozenset
      value = frozenset(s)
      value.add(6) # raise error
    

Array

  • Unlike lists, arrays are fixed in size and can only hold elements of the same data type.

  • Arrays provide faster access and better memory efficiency compared to lists when working with large amounts of data.

      import array
    
      # Creating an array of integers
      int_array = array.array('i', [1, 2, 3, 4, 5])
    
      # Creating an array of floating-point numbers
      float_array = array.array('f', [1.0, 2.5, 3.7, 4.2])
    
      print(int_array)      # Output: array('i', [1, 2, 3, 4, 5])
      print(float_array)    # Output: array('f', [1.0, 2.5, 3.7, 4.2])
    

Stacks(LIFOS)

  • A stack is a linear data structure that follows the First-In-Last-Out (FILO) principle.

  • It operates in a similar way to a stack of objects, where the last object placed on top is the first one to be removed.

      # Create an empty stack
      stack_value = []
    
      # Push elements onto the stack
      stack_value.append(10)
      stack_value.append(20)
      stack_value.append(30)
    
      # Pop elements from the stack
      print(stack_value.pop())  # Output: 30
      print(stack_value.pop())  # Output: 20
    
      # Check if the stack is empty
      print(len(stack_value) == 0)  # Output: False
    
      # Get the size of the stack
      print(len(stack_value))  # Output: 1
    

Queues(FIFOS)

  • A queue is a linear data structure that follows the First-In-First-Out (FIFO) principle.

  • It works similarly to a real-world queue, where the person who arrives first is served first.

  • In a queue, elements are added at the tail(end) and removed from the head(front).

      import queue
    
      queue_value = queue.Queue()# Create a queue object
    
      # Enqueue(add) elements into the queue
      queue_value.put(10)
      queue_value.put(20)
      queue_value.put(30)
      print(queue_value)#<queue.Queue object at 0x7fb483786b80>
    
      # Dequeue(get and remove) elements from the front of the queue
      print(queue_value.get())  # Output: 10
      print(queue_value.get())  # Output: 20
    
      # Check if the queue is empty
      print(queue_value.empty())  # Output: False
    
      # Get the size of the queue
      print(queue_value.qsize())  # Output: 1
    

Priority Queues

  • A priority queue is a data structure where elements are assigned priorities and the element with the highest priority is dequeued first.

  • Elements are enqueued with a priority value, and the queue automatically sorts the elements based on their priorities.

      import queue
    
      priority_queue = queue.PriorityQueue()# Create a priority queue object
    
      # Enqueue elements into the priority queue
      priority_queue.put((3, "Apple"))
      priority_queue.put((1, "Banana"))
      priority_queue.put((2, "Orange"))
    
      # Dequeue elements from the priority queue
      print(priority_queue.get())  # Output: (1, 'Banana')
      print(priority_queue.get())  # Output: (2, 'Orange')
    
      # Check if the priority queue is empty
      print(priority_queue.empty())  # Output: False
    
      # Get the size of the priority queue
      print(priority_queue.qsize())  # Output: 1