Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Complexity Cheat Sheet for Python Operations
Time complexity measures how algorithm execution time grows with input size. It uses Big O notation to set an upper bound on worst-case performance. Understanding complexity helps you choose the right data structures and optimize your code.
For example, an O(n) algorithm takes twice as long with double input size, while an O(n²) algorithm takes four times longer with double input size.
List Time Complexity
Lists are implemented as dynamic arrays in Python. Here's the time complexity cheat sheet for list operations ?
| Operation | Average Case | Amortized Worst Case |
|---|---|---|
| Copy | O(n) | O(n) |
| Append | O(1) | O(1) |
| Pop last | O(1) | O(1) |
| Pop intermediate | O(n) | O(n) |
| Insert | O(n) | O(n) |
| Get Item | O(1) | O(1) |
| Set Item | O(1) | O(1) |
| Delete Item | O(n) | O(n) |
| Iteration | O(n) | O(n) |
| Get Slice | O(k) | O(k) |
| Del Slice | O(n) | O(n) |
| Set Slice | O(k+n) | O(k+n) |
| Extend | O(k) | O(k) |
| Sort | O(n log n) | O(n log n) |
| Multiply | O(nk) | O(nk) |
| x in s | O(n) | O(n) |
| min(s), max(s) | O(n) | O(n) |
| Get Length | O(1) | O(1) |
Here n is the number of elements in the list and k is either a parameter value or the number of elements in the parameter.
Example
# Demonstrating different list operation complexities
import time
# O(1) operations - constant time
data = [1, 2, 3, 4, 5]
print("Append (O(1)):", end=" ")
data.append(6)
print(data)
print("Pop last (O(1)):", end=" ")
data.pop()
print(data)
# O(n) operations - linear time
print("Insert at beginning (O(n)):", end=" ")
data.insert(0, 0)
print(data)
print("Search element (O(n)):", 3 in data)
Append (O(1)): [1, 2, 3, 4, 5, 6] Pop last (O(1)): [1, 2, 3, 4, 5] Insert at beginning (O(n)): [0, 1, 2, 3, 4, 5] Search element (O(n)): True
Collections.deque
A deque (double-ended queue) is implemented as a doubly linked list, making it efficient for operations at both ends ?
| Operation | Average Case | Amortized Worst Case |
|---|---|---|
| Copy | O(n) | O(n) |
| append | O(1) | O(1) |
| appendleft | O(1) | O(1) |
| pop | O(1) | O(1) |
| popleft | O(1) | O(1) |
| extend | O(k) | O(k) |
| extendleft | O(k) | O(k) |
| rotate | O(k) | O(k) |
| remove | O(n) | O(n) |
| Get Length | O(1) | O(1) |
Example
from collections import deque
# Deque operations - efficient at both ends
dq = deque([1, 2, 3])
print("Initial deque:", dq)
# O(1) operations at both ends
dq.appendleft(0)
dq.append(4)
print("After appendleft(0) and append(4):", dq)
dq.popleft()
dq.pop()
print("After popleft() and pop():", dq)
Initial deque: deque([1, 2, 3]) After appendleft(0) and append(4): deque([0, 1, 2, 3, 4]) After popleft() and pop(): deque([1, 2, 3])
Set
Sets use hash tables for fast membership testing and set operations ?
| Operation | Average Case | Worst Case |
|---|---|---|
| x in s | O(1) | O(n) |
| Union s|t | O(len(s)+len(t)) | O(len(s)+len(t)) |
| Intersection s&t | O(min(len(s), len(t))) | O(len(s) * len(t)) |
| Difference s-t | O(len(s)) | O(len(s)) |
| Symmetric Difference s^t | O(len(s)) | O(len(s) * len(t)) |
Example
# Set operations demonstration
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
# O(1) membership test
print("3 in set1:", 3 in set1)
# Set operations
print("Union:", set1 | set2)
print("Intersection:", set1 & set2)
print("Difference:", set1 - set2)
print("Symmetric difference:", set1 ^ set2)
3 in set1: True
Union: {1, 2, 3, 4, 5, 6}
Intersection: {3, 4}
Difference: {1, 2}
Symmetric difference: {1, 2, 5, 6}
Dictionary
Dictionaries use hash tables for fast key-based access ?
| Operation | Average Case | Amortized Worst Case |
|---|---|---|
| k in d | O(1) | O(n) |
| Copy | O(n) | O(n) |
| Get Item | O(1) | O(n) |
| Set Item | O(1) | O(n) |
| Delete Item | O(1) | O(n) |
| Iteration | O(n) | O(n) |
Example
# Dictionary operations demonstration
student_grades = {'Alice': 85, 'Bob': 92, 'Charlie': 78}
# O(1) operations
print("Get Alice's grade:", student_grades['Alice'])
print("Check if 'Bob' exists:", 'Bob' in student_grades)
# Add/update - O(1)
student_grades['David'] = 88
print("After adding David:", student_grades)
# Delete - O(1)
del student_grades['Charlie']
print("After removing Charlie:", student_grades)
Get Alice's grade: 85
Check if 'Bob' exists: True
After adding David: {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'David': 88}
After removing Charlie: {'Alice': 85, 'Bob': 92, 'David': 88}
Conclusion
Understanding time complexity helps you choose the right data structure for your needs. Use lists for indexed access, deques for efficient end operations, sets for fast membership testing, and dictionaries for key-value mappings.
