Data Structures in Python Part 1
Data Structures in Python Part 1
# Accessing an element
# Removing an element
print(numbers[0])
numbers.remove(4)
print(numbers)
# Modifying an element
numbers[2] = 10 # Iterating through the list
print(numbers[2]) for num in numbers:
print(num)
Tuples
A tuple in Python is an ordered, immutable collection of elements.
Like lists, tuples can hold a variety of data types, including other
tuples or complex objects. Tuples are defined using parentheses ( )
with elements separated by commas. While they resemble lists, the
key difference is that tuples cannot be modified after they are
created.
Tuple Key Characteristics:
• Ordered: Tuples maintain the element order, and each item can be accessed
using its index.
• Immutable: Once a tuple is created, its contents cannot be changed. This
makes tuples usable as keys in dictionaries.
• Faster than lists: Due to immutability, tuples are slightly more memory-
efficient and perform better in situations where data doesn’t need to change.
• Can contain duplicates: Tuples can hold repeated values.
• Support nesting: Tuples can contain other tuples, lists, dictionaries, etc.
• Indexable and iterable: Elements can be accessed using indexing and iterated
through with loops.
# Creating a tuple
person = ("Alice", 30, "Engineer")
# Accessing an element
print(person[0])
# Adding an element
fruits.add("orange") # Set operations
print(fruits) set1 = {1, 2, 3}
set2 = {3, 4, 5}
# Removing an element
fruits.remove("banana") print(set1.union(set2))
print(fruits) print(set1.intersection(set2))
print(set1.difference(set2))
Stacks
A stack is a linear data structure that operates on the Last In, First
Out (LIFO) principle. This means the last element that is added to
the stack is the first one to be removed. Stacks can be
implemented using Python lists or linked lists and are widely used
in situations where we need to keep track of operations or data in
reverse order.
Think of a stack like a stack of plates - only the topmost plate can be
removed or accessed first.
Key Characteristics:
• LIFO behavior: The last item pushed to the stack is the first one to
be popped off.
• Two primary operations:
• push: Insert an item at the top of the stack.
• pop: Discard an item from the top of the stack.
• Peek/top operation: View the item at the top without removing it.
• Multiple use cases: Used in recursion, backtracking, and parsing
algorithms.
Advantages
• Easy to implement: Stacks can be implemented easily using Python lists or
deque.
• Efficient for specific operations: Operations like undo/redo, function calls, and
backtracking are efficiently handled using stacks.
• Memory efficient: Stacks require only a small amount of additional memory
for pointer management.
• Thread-safety: Using queue.LifoQueue ensures thread-safe operations,
making it useful in concurrent applications.
• Fast performance: collections.deque offers O(1) complexity for push and pop
operations, making it an optimal choice.
• Used in algorithm implementations: Stacks are crucial in algorithms like
depth-first search (DFS) and balanced parenthesis checking.
• Supports various implementations: Python offers multiple ways to implement
stacks, catering to different performance and use-case needs.
• Better performance than lists for stacks: deque outperforms lists when used
as a stack due to optimized memory management.
Disadvantages of Stack in Python
• Limited flexibility: Since stacks operate in LIFO order, accessing elements
other than the top element is inefficient.
• Memory usage: If not managed properly, stacks can cause excessive memory
consumption, leading to stack overflow errors.
• Performance issues with lists: Lists in Python are dynamically resized, which
can cause inefficiencies in stack operations.
• Not suitable for all applications: While stacks are useful for specific scenarios,
they are not always the best choice for general data storage.
• Risk of stack overflow: If recursion depth is too high, it may lead to stack
overflow errors in recursive algorithms.
• Thread synchronization overhead: LifoQueue ensures thread safety, but this
comes at the cost of additional overhead in synchronization.
• No direct index access: Unlike lists, stacks do not allow direct access to
arbitrary elements.
Queues
A queue is a linear data structure that utilizes the First In, First Out
(FIFO) principle. In a queue, the first element that is added is the
first one to be removed - just like people waiting in line. New
elements are added at the rear (end), and elements are removed
from the front (beginning).
Queues can be implemented using lists, collections.deque, or linked
lists in Python, with deque being the most efficient and
recommended option for performance.
Adding an element to the FIFO queue is commonly referred to as an
enqueue operation, while retrieving one from it is known as a
dequeue operation.