Sobes.tech
Middle+

How would you build a data structure if the list data type did not exist in Python?

sobes.tech AI

Answer from AI

It is possible to emulate a list using a dictionary, where keys are numerical indices and values are list elements.

# Example of list emulation
data = {}  # Using a dictionary
size = 0

def append(item):
    global size
    data[size] = item
    size += 1

def get(index):
    if 0 <= index < size:
        return data[index]
    else:
        raise IndexError("Index out of range")

def set_item(index, item):
    if 0 <= index < size:
        data[index] = item
    else:
        raise IndexError("Index out of range")

def pop():
    global size
    if size > 0:
        size -= 1
        item = data[size]
        del data[size]
        return item
    else:
        raise IndexError("Pop from empty list")

# Usage
append(10)
append(20)
append(30)

print(get(1))  # Output: 20

set_item(0, 5)
print(get(0))  # Output: 5

print(pop())   # Output: 30
print(size)    # Output: 2

Advantages:

  • Allows storing elements in an ordered manner with index access.
  • Supports dynamic resizing.

Disadvantages:

  • Requires manual management of size and indices.
  • Insertions or deletions at the beginning or middle of the "list" are less efficient than with the native list type, as shifting elements may be necessary (though in this example, pop is implemented for the end).

An alternative, more complex approach, is to use linked lists (singly or doubly linked), implemented with classes.

class Node:
    def __init__(self, data=None):
        self.data = data
        self.next = None # Node of a singly linked list

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        last_node = self.head
        while last_node.next:
            last_node = last_node.next
        last_node.next = new_node

    def display(self):
        elements = []
        current = self.head
        while current:
            elements.append(current.data)
            current = current.next
        print(elements)

    # Additional operations (get, delete, etc.) would require extra code

# Usage
my_list = LinkedList()
my_list.append(1)
my_list.append(2)
my_list.append(3)
my_list.display() # Output: [1, 2, 3]

Advantages:

  • Efficient insertions and deletions at the beginning or middle of the list (with references).

Disadvantages:

  • More complex implementation.
  • Access by index requires traversal from the start, which is less efficient than direct access in a dictionary or native list.