# Part 3: Python Collections - Quick Review for Experienced Developers
This document provides a quick reference to Python's advanced and specialized collection types from the `collections` module.
---
### 1. Sorting: `sort()` vs `sorted()`
-**`list.sort()`**: In-place sort. Modifies the original list and returns `None`.
```python
my_list=[3,1,2]
my_list.sort()# my_list is now [1, 2, 3]
```
-**`sorted()`**: Built-in function. Returns a *new* sorted list, leaving the original unchanged.
```python
original_list=[3,1,2]
new_list=sorted(original_list)# new_list is [1, 2, 3], original_list is unchanged
```
---
### 2. Tuple Unpacking
-**Basic Unpacking**:
```python
a,b=(10,20)
```
-**Extended Unpacking (`*`)**:
```python
first,*middle,last=[1,2,3,4,5]
# first -> 1
# middle -> [2, 3, 4]
# last -> 5
```
---
### 3. Specialized Collections in `collections`
A brief overview of useful classes in the `collections` module.
| Class | Description | Common Use Case |
| :--- | :--- | :--- |
| `Counter` | A `dict` subclass for counting hashable objects. | Counting item frequencies, finding most common items. |
| `defaultdict`| A `dict` subclass that calls a factory function for missing keys. | Grouping items into lists or other collections without checking for key existence. |
| `deque` | "Double-ended queue". Fast appends and pops from both ends. | Implementing queues, stacks, or keeping a list of "last N" items. |
| `namedtuple` | Factory function for creating tuple subclasses with named fields. | Creating simple, immutable objects with attribute access for better readability. |
# Part 4: OOP in Python - Quick Review for Experienced Developers
This document provides a concise overview of Object-Oriented Programming (OOP) syntax and concepts in Python for developers familiar with OOP principles.
---
### 1. Classes and Objects
-**Basic Definition**: Use the `class` keyword. The first argument to instance methods is conventionally `self`.
-**`__init__`**: The constructor method.
-**`@dataclass`**: A decorator that auto-generates boilerplate code like `__init__()`, `__repr__()`, `__eq__()`, etc. Highly recommended for data-centric classes.
```python
fromdataclassesimportdataclass
@dataclass
classPoint:
x:float
y:float
defdistance_from_origin(self)->float:
return(self.x**2+self.y**2)**0.5
p=Point(3,4)
print(p.distance_from_origin())# Output: 5.0
```
---
### 2. Inheritance
-**Syntax**: `class ChildClass(ParentClass):`
-**`super()`**: Used to call methods from the parent class.
-**Method Overriding**: Simply define a method with the same name in the child class.
```python
@dataclass
classPoint3D(Point):# Inherits from Point
z:float
# Overriding the method
defdistance_from_origin(self)->float:
# Calling parent's method using super()
d_2d=super().distance_from_origin()
return(d_2d**2+self.z**2)**0.5
p3d=Point3D(3,4,12)
print(p3d.distance_from_origin())# Output: 13.0
```
---
### 3. Encapsulation
-**Convention, not Enforcement**: Python doesn't have `private` or `protected` keywords like Java/C++.
-**`_` (Single Underscore) Prefix**: A convention indicating an attribute is for internal use (protected).
-**`__` (Double Underscore) Prefix**: "Name mangling". The interpreter changes the name to `_ClassName__attribute`, making it harder to access from outside but not truly private.
```python
classMyClass:
def__init__(self):
self._internal_var=1# Convention for internal use
self.__mangled_var=2# Name is mangled
defget_mangled(self):
returnself.__mangled_var
obj=MyClass()
print(obj._internal_var)# 1 (Accessible)
# print(obj.__mangled_var) # AttributeError
print(obj._MyClass__mangled_var)# 2 (Still accessible if you know the mangled name)
```
---
### 4. Abstraction
-**`abc` module**: Use the `ABC` (Abstract Base Class) and `@abstractmethod` decorator to define abstract classes and methods.
- Subclasses must implement all abstract methods to be instantiated.
```python
fromabcimportABC,abstractmethod
classShape(ABC):
@abstractmethod
defarea(self)->float:
pass
classSquare(Shape):
def__init__(self,side):
self.side=side
defarea(self)->float:# Must implement this method
returnself.side**2
# s = Shape() # TypeError: Can't instantiate abstract class
sq=Square(5)# OK
```
---
### 5. Magic Methods (Dunder Methods)
Methods with double underscores (`__method__`) that allow you to emulate the behavior of built-in types.