Essential Python Data Structures and Types
Lists
Lists represent ordered, mutable sequences capable of storing heterogeneous elements. Elements within a list can be duplicated.
Creation and Initialization
inventory = []
inventory = ['item_x', 'item_y']
inventory = list()
Accessing Elements
Indexing allows direct access to elements. Positive indices start from 0, while negative indices start from the end.
metrics = [55, 12, 89, 30, 4]
# First element
metrics[0] # 55
# Second element
metrics[1] # 12
# Last element
metrics[-1] # 4
# Second to last
metrics[-2] # 30
# Finding index (returns first occurrence)
metrics.index(89) # 2
# Counting occurrences
metrics.count(89) # 1
# Slicing [start:stop:step]
metrics[0:2] # [55, 12] (excludes stop index)
metrics[-2:] # [30, 4]
metrics[:2] # [55, 12]
metrics[::2] # [55, 89, 4] (step of 2)
Modification and Updates
Lists support dynamic modification.
metrics = [55, 12, 89, 30, 4]
metrics.append(100) # [55, 12, 89, 30, 4, 100]
metrics.insert(1, 7) # [55, 7, 12, 89, 30, 4, 100]
metrics[0] = 'updated' # ['updated', 7, 12, 89, 30, 4, 100]
# Slice assignment replaces the section
metrics[0:3] = ['a', 'b', 'c']
# Result: ['a', 'b', 'c', 89, 30, 4, 100]
Removal Operations
metrics = [55, 12, 89, 30, 4]
# Pop removes and returns the last item
last = metrics.pop() # returns 4, list becomes [55, 12, 89, 30]
# Remove deletes the first matching value
metrics.remove(12) # [55, 89, 30]
# Del statement removes by index or slice
del metrics[1] # [55, 30]
del metrics[:1] # [30]
Iteration
metrics = [55, 12, 89, 30, 4]
# Standard loop
for val in metrics:
print(val)
# Using enumerate for index and value
for idx, val in enumerate(metrics):
print(f"Index: {idx}, Value: {val}")
# Range generates a sequence of numbers
# Python 3 returns a range object, not a list
list(range(5)) # [0, 1, 2, 3, 4]
Sorting and Ordering
chars = ['z', 'a', 'B', 'A']
chars.sort() # Sorts in place based on ASCII/Unicode
# Result: ['A', 'B', 'a', 'z']
chars.reverse() # Reverses the list in place
Concatenation and Repetition
list_a = [1, 2]
list_b = [3, 4]
combined = list_a + list_b # [1, 2, 3, 4]
repeated = list_a * 2 # [1, 2, 1, 2]
list_a.extend(list_b) # list_a becomes [1, 2, 3, 4]
Copying Mechanisms
Understanding reference vs copy is critical.
import copy
# Reference assignment (no copy)
original = [1, 2, 3]
ref = original
original[0] = 99
# ref is now [99, 2, 3]
# Shallow Copy (copies parent, not children)
original = [1, 2, [3, 4]]
shallow = original.copy()
original[2][0] = 99
# shallow is [1, 2, [99, 4]]
# Deep Copy (recursive copy)
original = [1, 2, [3, 4]]
deep = copy.deepcopy(original)
original[2][0] = 99
# deep remains [1, 2, [3, 4]]
Strings
Strings are immutable sequences of characters.
Case Manipulation
text = "PyThon CODING"
text.swapcase() # "pYthoN coding"
text.title() # "Python Coding"
text.capitalize() # "Python coding"
text.lower() # "python coding"
text.upper() # "PYTHON CODING"
text.casefold() # "python coding" (aggressive lowercasing)
Alignment and Padding
text = "hello"
text.center(10, '*') # '**hello***'
text.zfill(5) # 'hello' (no change if len >= width)
"5".zfill(3) # '005'
Search and Count
text = "banana"
text.count('a') # 3
text.count('a', 2) # 2 (start from index 2)
text.endswith('na') # True
text.startswith('ba') # True
text.find('n') # 2 (returns -1 if missing)
text.index('n') # 2 (raises ValueError if missing)
Formatting and Translation
# Format method
template = "User: {0}, Age: {1}"
template.format("Alice", 30)
named_template = "User: {name}, Age: {age}"
named_template.format(name="Bob", age=25)
# Translation table
intab = "abc"
outtab = "123"
trans_table = str.maketrans(intab, outtab)
"cab".translate(trans_table) # "312"
Validation Methods
"abc123".isalnum() # True (letters + numbers)
"abc".isalpha() # True (letters only)
"123".isdigit() # True
"123".isdecimal() # True
"var_name".isidentifier() # True (valid variable name)
"text".islower() # True
"TEXT".isupper() # True
" ".isspace() # True
"Title".istitle() # True
"no\nbreak".isprintable() # False
Splitting and Joining
data = "apple,banana,cherry"
data.split(',') # ['apple', 'banana', 'cherry']
data.partition(',') # ('apple', ',', 'banana,cherry')
# Joining requires string iterable
items = ['1', '2', '3']
"-".join(items) # '1-2-3'
Trimming
raw = " content \n"
raw.strip() # "content"
raw.lstrip() # "content \n"
raw.rstrip() # " content"
Tuples
Tuples are immutable sequences. Once created, their structure cannot change, though mutable elements inside them (like lists) can be modified.
# Declaration
coords = tuple()
coords = ()
coords = (10, 20)
single = (5,) # Comma required for single element
# Methods
coords.count(10) # 1
coords.index(20) # 1
# Nested mutability example
container = (1, 2, [3, 4])
container[2][0] = 99
# Result: (1, 2, [99, 4])
Dictionaries
Dictionaries are unordered mappings of key-value pairs. Keys must be hashable (immutable) and unique.
config = {
'host': 'localhost',
'port': 8080,
'debug': True
}
# Access
config['host'] # 'localhost'
config.get('port') # 8080
config.get('user', 'admin') # 'admin' (default if missing)
# Modification
config['debug'] = False
config['new_key'] = 'value'
# Removal
config.pop('host')
del config['port']
config.popitem() # Removes arbitrary item
# Utilities
config.clear() # Empties dict
config.keys() # View of keys
config.values() # View of values
config.items() # View of (key, value) pairs
# Update and SetDefault
updates = {'port': 9000, 'timeout': 30}
config.update(updates)
config.setdefault('timeout', 60) # Returns existing or sets default
# Creating from keys
dict.fromkeys(['a', 'b'], 0) # {'a': 0, 'b': 0}
Hashing
Hashing converts data into a fixed-size integer. In Python, this mechanism underpins dictionaries and sets. Only immutable objects (like numbers, strings, tuples) can be hashed.
hash("stable_string") # Returns an integer
hash(123) # Returns an integer
# hash([1, 2]) # Raises TypeError (lists are unhashable)
Sets
Set are unordered collections of unique elements. They are optimized for membership testing and mathematical set operations.
group_a = {1, 2, 3, 4}
group_b = {3, 4, 5, 6}
# Modification
group_a.add(5)
group_a.update([6, 7])
group_a.pop() # Removes random element
group_a.remove(2) # Raises error if missing
group_a.discard(2) # No error if missing
group_a.clear()
# Set Operations
intersection = group_a & group_b # {3, 4}
union = group_a | group_b # {1, 2, 3, 4, 5, 6}
difference = group_a - group_b # {1, 2}
symmetric_diff = group_a ^ group_b # {1, 2, 5, 6}
# Comparisons
group_a.issubset(group_b)
group_a.issuperset(group_b)
group_a.isdisjoint(group_b)
# In-place updates
group_a.intersection_update(group_b)