Comparison Operations via operator Module
The operator module provides function equivalents for standard comparison operators. Import it before use:
import operator
# Function-based comparisons
operator.gt(x, y) # Greater than: x > y
operator.ge(x, y) # Greater or equal: x >= y
operator.lt(x, y) # Less than: x < y
operator.le(x, y) # Less or equal: x <= y
operator.eq(x, y) # Equal: x == y
operator.ne(x, y) # Not equal: x != y
Practical application with data validation:
values = [15, 8, 22, 3]
threshold = 10
filtered = [v for v in values if operator.ge(v, threshold)]
# Result: [15, 22]
Object Copying: Reference vs. Duplicate
Understanding assignment, shallow copy, and deep copy behaviors:
import copy
original = {'owner': 'admin', 'scores': [85, 92, 78]}
reference = original
shallow_duplicate = original.copy()
deep_duplicate = copy.deepcopy(original)
original['owner'] = 'guest'
original['scores'].append(95)
print(f"Original: {original}")
print(f"Reference: {reference}")
print(f"Shallow copy: {shallow_duplicate}")
print(f"Deep copy: {deep_duplicate}")
Output demonstrates distinct behaviors:
Original: {'owner': 'guest', 'scores': [85, 92, 78, 95]}
Reference: {'owner': 'guest', 'scores': [85, 92, 78, 95]}
Shallow copy: {'owner': 'admin', 'scores': [85, 92, 78, 95]}
Deep copy: {'owner': 'admin', 'scores': [85, 92, 78]}
Key distinctions:
- Assignment creates a pointer to the same memory location
- Shallow copy constructs a new container but references original elements
- Deep copy recursively clones all nested objects, ensuring complete independence
Sequence Generation and Length Calculation
The range() constructor offers flexible iteration control:
# Single argument: 0 to n-1
list(range(5)) # [0, 1, 2, 3, 4]
# Two arguments: start to end-1
list(range(2, 7)) # [2, 3, 4, 5, 6]
# Three arguments: start to end-1 with step
list(range(0, 10, 2)) # [0, 2, 4, 6, 8]
The len() function returns element counts across container types:
text = "python programming"
len(text) # 18
items = ['red', 'green', 'blue', 'yellow']
len(items) # 4
mapping = {'id': 101, 'name': 'device', 'status': 'active'}
len(mapping) # 3
coordinates = (10, 20, 30)
len(coordinates) # 3
Customizing Print Termination
The print() function's end paramter controls output termination. By default, print() adds a newline. Specifying end overrides this behvaior:
data_points = [3.14, 2.71, 1.62, 1.41]
for value in data_points:
print(value, end=" | ")
Result: 3.14 | 2.71 | 1.62 | 1.41 |
Invoking Parent Class Methods
super() enables subclass access to overridden parent methods:
class Vehicle:
def describe(self):
return "Base transportation"
class ElectricCar(Vehicle):
def describe(self):
return "Electric vehicle"
def full_description(self):
child_info = self.describe()
parent_info = super().describe()
return f"{child_info} - {parent_info}"
model_s = ElectricCar()
print(model_s.describe()) # "Electric vehicle"
print(super(ElectricCar, model_s).describe()) # "Base transportation"
Examining Memory Addresses
The id() function reveals an object's memory location:
alpha = 100
beta = alpha
gamma = 200
print(id(alpha)) # 1401234567890 (example address)
print(id(beta)) # Same as alpha
print(id(gamma)) # Different address
Inline Function Definitions with lambda
Lambda expressions create compact, single-expression functions:
square = lambda num: num ** 2
print(square(7)) # 49
# Multiple parameters
add = lambda x, y: x + y
print(add(3, 5)) # 8
Factory pattern with lambda closures:
def multiplier_factory(factor):
return lambda value: value * factor
double = multiplier_factory(2)
triple = multiplier_factory(3)
print(double(15)) # 30
print(triple(15)) # 45
Lambda functions excel in higher-order function contexts:
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda n: n * n, numbers)) # [1, 4, 9, 16, 25]
evens = list(filter(lambda n: n % 2 == 0, numbers)) # [2, 4]