python-skills 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_skills/__init__.py +10 -0
- python_skills/__main__.py +6 -0
- python_skills/adapters/__init__.py +48 -0
- python_skills/adapters/agent_skills.py +415 -0
- python_skills/adapters/aider_adapter.py +226 -0
- python_skills/adapters/base.py +153 -0
- python_skills/adapters/claude.py +474 -0
- python_skills/adapters/cline.py +332 -0
- python_skills/adapters/codex.py +24 -0
- python_skills/adapters/continue_adapter.py +198 -0
- python_skills/adapters/cursor.py +327 -0
- python_skills/adapters/gemini.py +26 -0
- python_skills/adapters/goose.py +26 -0
- python_skills/adapters/junie.py +25 -0
- python_skills/adapters/kiro.py +382 -0
- python_skills/adapters/opencode.py +27 -0
- python_skills/adapters/roo.py +25 -0
- python_skills/adapters/universal.py +203 -0
- python_skills/adapters/vscode.py +27 -0
- python_skills/adapters/windsurf.py +26 -0
- python_skills/adapters/zed.py +27 -0
- python_skills/cli.py +326 -0
- python_skills/config.py +160 -0
- python_skills/detector.py +152 -0
- python_skills/installer.py +163 -0
- python_skills/markers.py +115 -0
- python_skills/skills/__init__.py +14 -0
- python_skills/skills/loader.py +171 -0
- python_skills/skills/metadata.py +152 -0
- python_skills/skills/registry.py +101 -0
- python_skills/state.py +204 -0
- python_skills-1.0.0.dist-info/METADATA +99 -0
- python_skills-1.0.0.dist-info/RECORD +105 -0
- python_skills-1.0.0.dist-info/WHEEL +4 -0
- python_skills-1.0.0.dist-info/entry_points.txt +2 -0
- python_skills-1.0.0.dist-info/licenses/LICENSE +21 -0
- skills/advanced_python.md +239 -0
- skills/anti_patterns/index.md +406 -0
- skills/comprehensions.md +167 -0
- skills/control_flow.md +175 -0
- skills/data_structures.md +243 -0
- skills/debugging/common_bugs.md +222 -0
- skills/debugging/inspection_techniques.md +249 -0
- skills/debugging/root_cause.md +203 -0
- skills/engineering/application_logging.md +195 -0
- skills/engineering/cli_apps.md +207 -0
- skills/engineering/configuration.md +218 -0
- skills/engineering/database.md +240 -0
- skills/engineering/dependency_management.md +205 -0
- skills/engineering/http_clients.md +267 -0
- skills/engineering/modules_packages.md +211 -0
- skills/engineering/packaging.md +197 -0
- skills/engineering/project_structure.md +155 -0
- skills/engineering/pyproject_toml.md +302 -0
- skills/engineering/virtual_environments.md +206 -0
- skills/functions.md +244 -0
- skills/generation/async_concurrency.md +291 -0
- skills/generation/error_handling.md +276 -0
- skills/generation/protocols_generics.md +243 -0
- skills/generation/type_hints.md +290 -0
- skills/generation/validation_pipeline.md +274 -0
- skills/generation/workflow.md +190 -0
- skills/oop.md +228 -0
- skills/quality/abstractions.md +154 -0
- skills/quality/comments.md +177 -0
- skills/quality/documentation.md +176 -0
- skills/quality/duplication.md +137 -0
- skills/quality/maintainability.md +142 -0
- skills/quality/naming.md +171 -0
- skills/quality/quality_functions.md +245 -0
- skills/quality/readability.md +239 -0
- skills/quality/type_annotations.md +192 -0
- skills/refactoring/behavior_preservation.md +157 -0
- skills/refactoring/incremental.md +187 -0
- skills/refactoring/interface_stability.md +199 -0
- skills/refactoring/safe_refactoring.md +206 -0
- skills/security/auth_boundaries.md +200 -0
- skills/security/command_injection.md +207 -0
- skills/security/dependency_risks.md +282 -0
- skills/security/file_handling.md +156 -0
- skills/security/input_validation.md +190 -0
- skills/security/path_traversal.md +172 -0
- skills/security/secrets.md +171 -0
- skills/security/sql_injection.md +188 -0
- skills/security/unsafe_deserialization.md +164 -0
- skills/stdlib/argparse.md +178 -0
- skills/stdlib/collections.md +212 -0
- skills/stdlib/datetime.md +187 -0
- skills/stdlib/functools.md +238 -0
- skills/stdlib/itertools.md +183 -0
- skills/stdlib/json.md +162 -0
- skills/stdlib/logging.md +185 -0
- skills/stdlib/os_sys.md +184 -0
- skills/stdlib/pathlib.md +218 -0
- skills/stdlib/re.md +171 -0
- skills/stdlib/statistics.md +112 -0
- skills/stdlib/subprocess.md +211 -0
- skills/testing/async_tests.md +249 -0
- skills/testing/coverage.md +168 -0
- skills/testing/edge_cases.md +197 -0
- skills/testing/fixtures_mocks.md +203 -0
- skills/testing/organization.md +205 -0
- skills/testing/parameterized.md +174 -0
- skills/testing/regression_tests.md +165 -0
- skills/variables_types.md +107 -0
skills/comprehensions.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Core: Comprehensions
|
|
2
|
+
|
|
3
|
+
**Purpose**: Python comprehension syntax and appropriate usage.
|
|
4
|
+
|
|
5
|
+
**When to use**: Transforming, filtering, or creating collections.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Core Rules
|
|
10
|
+
|
|
11
|
+
### List Comprehension
|
|
12
|
+
```python
|
|
13
|
+
# Basic
|
|
14
|
+
squares = [x * x for x in range(10)]
|
|
15
|
+
|
|
16
|
+
# With filter
|
|
17
|
+
evens = [x for x in range(10) if x % 2 == 0]
|
|
18
|
+
|
|
19
|
+
# Nested (cartesian product)
|
|
20
|
+
pairs = [(x, y) for x in range(3) for y in range(3)]
|
|
21
|
+
# [(0,0), (0,1), (0,2), (1,0), ...]
|
|
22
|
+
|
|
23
|
+
# With conditional expression (ternary)
|
|
24
|
+
labels = ["even" if x % 2 == 0 else "odd" for x in range(10)]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Dict Comprehension
|
|
28
|
+
```python
|
|
29
|
+
# Basic
|
|
30
|
+
name_to_len = {name: len(name) for name in names}
|
|
31
|
+
|
|
32
|
+
# With filter
|
|
33
|
+
short_names = {name: len(name) for name in names if len(name) < 5}
|
|
34
|
+
|
|
35
|
+
# Swap keys/values (values must be unique)
|
|
36
|
+
inverted = {v: k for k, v in mapping.items()}
|
|
37
|
+
|
|
38
|
+
# From two sequences
|
|
39
|
+
mapping = {k: v for k, v in zip(keys, values, strict=True)}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Set Comprehension
|
|
43
|
+
```python
|
|
44
|
+
unique_lengths = {len(name) for name in names}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Generator Expression
|
|
48
|
+
```python
|
|
49
|
+
# Lazy, memory efficient
|
|
50
|
+
squares_gen = (x * x for x in range(1_000_000))
|
|
51
|
+
|
|
52
|
+
# Consume
|
|
53
|
+
for sq in squares_gen:
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
# Or convert
|
|
57
|
+
list(squares_gen)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Walrus Operator (Python 3.8+)
|
|
63
|
+
```python
|
|
64
|
+
# Assign and use in comprehension
|
|
65
|
+
results = [y for x in data if (y := compute(x)) is not None]
|
|
66
|
+
|
|
67
|
+
# In while loops
|
|
68
|
+
while (line := file.readline()) != '':
|
|
69
|
+
process(line)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Decision Rules
|
|
75
|
+
|
|
76
|
+
| Situation | Choice |
|
|
77
|
+
|-----------|--------|
|
|
78
|
+
| Simple transform + filter | Comprehension |
|
|
79
|
+
| Multiple transforms, complex logic | Explicit `for` loop |
|
|
80
|
+
| Need to debug intermediate values | Explicit `for` loop |
|
|
81
|
+
| Large/unknown size, memory concern | Generator expression |
|
|
82
|
+
| Dict from two parallel sequences | `{k: v for k, v in zip(...)}` |
|
|
83
|
+
| Flatten nested list | `[item for sublist in nested for item in sublist]` |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Preferred Patterns
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
# Flatmap pattern
|
|
91
|
+
flattened = [item for sublist in nested for item in sublist]
|
|
92
|
+
|
|
93
|
+
# Grouping with defaultdict (clearer than comprehension)
|
|
94
|
+
from collections import defaultdict
|
|
95
|
+
grouped = defaultdict(list)
|
|
96
|
+
for item in items:
|
|
97
|
+
grouped[key(item)].append(item)
|
|
98
|
+
|
|
99
|
+
# Set for deduplication preserving order (Python 3.7+)
|
|
100
|
+
seen = set()
|
|
101
|
+
unique = [x for x in items if not (x in seen or seen.add(x))]
|
|
102
|
+
# Or simpler (loses order): list(set(items))
|
|
103
|
+
|
|
104
|
+
# Chained operations — prefer explicit loop
|
|
105
|
+
result = []
|
|
106
|
+
for item in items:
|
|
107
|
+
transformed = transform(item)
|
|
108
|
+
if validate(transformed):
|
|
109
|
+
result.append(transformed)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Avoid
|
|
115
|
+
|
|
116
|
+
- Nested comprehensions >2 levels deep (unreadable)
|
|
117
|
+
- Side effects in comprehensions (mutating external state)
|
|
118
|
+
- Complex conditional expressions (ternary) in comprehensions
|
|
119
|
+
- Generator expressions passed directly to functions that consume immediately (just use list comprehension)
|
|
120
|
+
- Walrus operator for trivial assignments (reduces readability)
|
|
121
|
+
- Comprehensions spanning multiple lines without clear structure
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Anti-Patterns
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
# BAD: Side effect
|
|
129
|
+
[x.append(i) for i in range(10)] # Returns [None, None, ...]
|
|
130
|
+
|
|
131
|
+
# BAD: Too complex
|
|
132
|
+
result = [
|
|
133
|
+
transform(x)
|
|
134
|
+
for x in items
|
|
135
|
+
if (cond1 := check1(x))
|
|
136
|
+
and (cond2 := check2(x) if cond1 else False)
|
|
137
|
+
for y in related(x)
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
# GOOD: Explicit loop
|
|
141
|
+
result = []
|
|
142
|
+
for x in items:
|
|
143
|
+
if not check1(x):
|
|
144
|
+
continue
|
|
145
|
+
if not check2(x):
|
|
146
|
+
continue
|
|
147
|
+
for y in related(x):
|
|
148
|
+
result.append(transform(x))
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Validation Considerations
|
|
154
|
+
|
|
155
|
+
- Type checkers infer comprehension types
|
|
156
|
+
- Linters flag overly complex comprehensions
|
|
157
|
+
- Memory profile for large comprehensions vs generators
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Related Skills
|
|
162
|
+
|
|
163
|
+
- `core/data_structures.md`
|
|
164
|
+
- `core/advanced_python.md` (generators)
|
|
165
|
+
- `generation/type_hints.md`
|
|
166
|
+
- `quality/readability.md`
|
|
167
|
+
- `anti_patterns/index.md`
|
skills/control_flow.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Core: Control Flow
|
|
2
|
+
|
|
3
|
+
**Purpose**: Python control flow constructs and patterns.
|
|
4
|
+
|
|
5
|
+
**When to use**: Always active. Foundation for logic implementation.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Core Rules
|
|
10
|
+
|
|
11
|
+
### Conditionals
|
|
12
|
+
```python
|
|
13
|
+
if condition:
|
|
14
|
+
...
|
|
15
|
+
elif other_condition:
|
|
16
|
+
...
|
|
17
|
+
else:
|
|
18
|
+
...
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
- No parentheses required around condition
|
|
22
|
+
- `elif` not `else if`
|
|
23
|
+
- Truthiness: `None`, `False`, `0`, `0.0`, `""`, `[]`, `{}`, `set()` are falsy
|
|
24
|
+
- Use explicit comparisons (`is None`, `== 0`, `== ""`) when falsy is a valid value
|
|
25
|
+
|
|
26
|
+
### Ternary Expression
|
|
27
|
+
```python
|
|
28
|
+
value = true_expr if condition else false_expr
|
|
29
|
+
```
|
|
30
|
+
- Single expression, not statement
|
|
31
|
+
- Use for simple assignments only
|
|
32
|
+
|
|
33
|
+
### Match Statement (Python 3.10+)
|
|
34
|
+
```python
|
|
35
|
+
match value:
|
|
36
|
+
case pattern1:
|
|
37
|
+
...
|
|
38
|
+
case pattern2 if guard:
|
|
39
|
+
...
|
|
40
|
+
case _:
|
|
41
|
+
...
|
|
42
|
+
```
|
|
43
|
+
- Structural pattern matching
|
|
44
|
+
- Use for complex data structure dispatch
|
|
45
|
+
- Guard clauses with `if`
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Loops
|
|
50
|
+
|
|
51
|
+
### For Loop (Iteration)
|
|
52
|
+
```python
|
|
53
|
+
for item in iterable:
|
|
54
|
+
...
|
|
55
|
+
else: # executes if loop completes without break
|
|
56
|
+
...
|
|
57
|
+
```
|
|
58
|
+
- `else` clause runs on normal completion (no `break`)
|
|
59
|
+
- Preferred over index-based loops
|
|
60
|
+
|
|
61
|
+
### While Loop
|
|
62
|
+
```python
|
|
63
|
+
while condition:
|
|
64
|
+
...
|
|
65
|
+
else:
|
|
66
|
+
...
|
|
67
|
+
```
|
|
68
|
+
- `else` runs when condition becomes false (no `break`)
|
|
69
|
+
|
|
70
|
+
### Loop Control
|
|
71
|
+
- `break` — exit loop immediately
|
|
72
|
+
- `continue` — skip to next iteration
|
|
73
|
+
- `pass` — placeholder (no-op)
|
|
74
|
+
|
|
75
|
+
### Enumerate and Zip
|
|
76
|
+
```python
|
|
77
|
+
for i, item in enumerate(iterable, start=1):
|
|
78
|
+
...
|
|
79
|
+
|
|
80
|
+
for a, b in zip(list1, list2, strict=True): # Python 3.10+
|
|
81
|
+
...
|
|
82
|
+
```
|
|
83
|
+
- `strict=True` raises `ValueError` if lengths differ (Python 3.10+)
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Exception Control Flow
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
try:
|
|
91
|
+
risky_operation()
|
|
92
|
+
except SpecificError as e:
|
|
93
|
+
handle(e)
|
|
94
|
+
except (Error1, Error2) as e:
|
|
95
|
+
handle(e)
|
|
96
|
+
else: # runs if no exception
|
|
97
|
+
success_path()
|
|
98
|
+
finally: # always runs
|
|
99
|
+
cleanup()
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- Order: specific exceptions first, general last
|
|
103
|
+
- `else` block for code that should only run on success
|
|
104
|
+
- `finally` for cleanup (files, locks, connections)
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Decision Rules
|
|
109
|
+
|
|
110
|
+
| Situation | Construct |
|
|
111
|
+
|-----------|-----------|
|
|
112
|
+
| Simple branch | `if/elif/else` |
|
|
113
|
+
| Value-based dispatch (3.10+) | `match/case` |
|
|
114
|
+
| Iterate known collection | `for` |
|
|
115
|
+
| Iterate with index | `enumerate()` |
|
|
116
|
+
| Iterate multiple aligned collections | `zip(strict=True)` |
|
|
117
|
+
| Unknown iteration count | `while` |
|
|
118
|
+
| Early exit on condition | `break` |
|
|
119
|
+
| Skip iteration | `continue` |
|
|
120
|
+
| Cleanup always | `finally` |
|
|
121
|
+
| Success-only path | `else` on `try` |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Preferred Patterns
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
# EAFP (Easier to Ask Forgiveness than Permission)
|
|
129
|
+
try:
|
|
130
|
+
value = mapping[key]
|
|
131
|
+
except KeyError:
|
|
132
|
+
value = default
|
|
133
|
+
|
|
134
|
+
# LBYL (Look Before You Leap) - when appropriate
|
|
135
|
+
if key in mapping:
|
|
136
|
+
value = mapping[key]
|
|
137
|
+
else:
|
|
138
|
+
value = default
|
|
139
|
+
|
|
140
|
+
# Loop with else for search
|
|
141
|
+
for item in items:
|
|
142
|
+
if condition(item):
|
|
143
|
+
found = item
|
|
144
|
+
break
|
|
145
|
+
else:
|
|
146
|
+
found = default
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Avoid
|
|
152
|
+
|
|
153
|
+
- Deeply nested conditionals (refactor to functions/early returns)
|
|
154
|
+
- `for i in range(len(list))` — use `enumerate` or direct iteration
|
|
155
|
+
- `while True` with `break` when `for` or `itertools` works
|
|
156
|
+
- Catching `Exception` or bare `except:` (see error_handling.md)
|
|
157
|
+
- Using exceptions for normal control flow (except EAFP patterns)
|
|
158
|
+
- Complex logic in ternary expressions
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Validation Considerations
|
|
163
|
+
|
|
164
|
+
- Linters catch unreachable code after `return`/`break`/`continue`
|
|
165
|
+
- Type checkers verify exhaustive `match` (with `assert_never`)
|
|
166
|
+
- Coverage tools reveal untested branches
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Related Skills
|
|
171
|
+
|
|
172
|
+
- `core/functions.md` (early returns)
|
|
173
|
+
- `generation/error_handling.md`
|
|
174
|
+
- `generation/async_concurrency.md` (async for/while)
|
|
175
|
+
- `anti_patterns/index.md`
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# Core: Data Structures
|
|
2
|
+
|
|
3
|
+
**Purpose**: Python built-in data structures and their appropriate use.
|
|
4
|
+
|
|
5
|
+
**When to use**: Always active. Choose the right structure for the problem.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Core Rules
|
|
10
|
+
|
|
11
|
+
### List (`list`)
|
|
12
|
+
- Ordered, mutable, allows duplicates
|
|
13
|
+
- O(1) append, pop from end; O(n) insert/pop from front
|
|
14
|
+
- Use for sequences where order matters
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
items: list[str] = ["a", "b", "c"]
|
|
18
|
+
items.append("d")
|
|
19
|
+
items.extend(["e", "f"])
|
|
20
|
+
items.insert(0, "start")
|
|
21
|
+
popped = items.pop() # From end
|
|
22
|
+
popped = items.pop(0) # From front (O(n))
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Tuple (`tuple`)
|
|
26
|
+
- Ordered, immutable, allows duplicates
|
|
27
|
+
- Lightweight, hashable (if contents hashable)
|
|
28
|
+
- Use for fixed collections, heterogeneous data, return values
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
point: tuple[float, float] = (1.0, 2.0)
|
|
32
|
+
# Unpacking
|
|
33
|
+
x, y = point
|
|
34
|
+
# Named tuple alternative
|
|
35
|
+
from typing import NamedTuple
|
|
36
|
+
class Point(NamedTuple):
|
|
37
|
+
x: float
|
|
38
|
+
y: float
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Dict (`dict`)
|
|
42
|
+
- Key-value mapping, mutable, keys unique and hashable
|
|
43
|
+
- O(1) average lookup, insertion, deletion
|
|
44
|
+
- Preserves insertion order (Python 3.7+)
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
data: dict[str, int] = {"a": 1, "b": 2}
|
|
48
|
+
data["c"] = 3
|
|
49
|
+
value = data.get("key", default) # Safe access
|
|
50
|
+
value = data.setdefault("key", default) # Get or set
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Set (`set`) / Frozenset (`frozenset`)
|
|
54
|
+
- Unordered, unique elements, mutable (`set`) or immutable (`frozenset`)
|
|
55
|
+
- O(1) membership testing
|
|
56
|
+
- Mathematical set operations
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
unique: set[int] = {1, 2, 3}
|
|
60
|
+
unique.add(4)
|
|
61
|
+
unique.update([5, 6])
|
|
62
|
+
intersection = unique & {3, 4, 5}
|
|
63
|
+
union = unique | {7, 8}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Nesting and Composition
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
# List of dicts
|
|
72
|
+
records: list[dict[str, Any]] = [{"id": 1, "name": "a"}, {"id": 2, "name": "b"}]
|
|
73
|
+
|
|
74
|
+
# Dict of lists
|
|
75
|
+
grouped: dict[str, list[int]] = {"even": [2, 4], "odd": [1, 3]}
|
|
76
|
+
|
|
77
|
+
# Complex nesting
|
|
78
|
+
matrix: list[list[int]] = [[1, 2], [3, 4]]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Indexing and Slicing
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
seq = [0, 1, 2, 3, 4, 5]
|
|
87
|
+
|
|
88
|
+
seq[0] # First
|
|
89
|
+
seq[-1] # Last
|
|
90
|
+
seq[1:4] # Indices 1,2,3
|
|
91
|
+
seq[:3] # First 3
|
|
92
|
+
seq[3:] # From index 3
|
|
93
|
+
seq[::2] # Every 2nd
|
|
94
|
+
seq[::-1] # Reversed
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- Slicing returns new object (shallow copy)
|
|
98
|
+
- Out-of-range slice indices don't raise (clamped)
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Unpacking
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# Basic
|
|
106
|
+
a, b, c = (1, 2, 3)
|
|
107
|
+
|
|
108
|
+
# Extended (Python 3+)
|
|
109
|
+
first, *middle, last = [1, 2, 3, 4, 5]
|
|
110
|
+
# first=1, middle=[2,3,4], last=5
|
|
111
|
+
|
|
112
|
+
# Ignored values
|
|
113
|
+
_, _, value = get_triple()
|
|
114
|
+
|
|
115
|
+
# Dict unpacking (Python 3.5+)
|
|
116
|
+
{**dict1, **dict2} # Merge (later wins)
|
|
117
|
+
{**dict1, "new": value} # Add key
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Iteration Patterns
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
# Direct iteration
|
|
126
|
+
for item in items:
|
|
127
|
+
...
|
|
128
|
+
|
|
129
|
+
# With index
|
|
130
|
+
for i, item in enumerate(items):
|
|
131
|
+
...
|
|
132
|
+
|
|
133
|
+
# Multiple sequences
|
|
134
|
+
for a, b in zip(list1, list2, strict=True):
|
|
135
|
+
...
|
|
136
|
+
|
|
137
|
+
# Reverse
|
|
138
|
+
for item in reversed(items):
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
# Sorted
|
|
142
|
+
for item in sorted(items):
|
|
143
|
+
...
|
|
144
|
+
|
|
145
|
+
# Dictionary
|
|
146
|
+
for key, value in mapping.items():
|
|
147
|
+
...
|
|
148
|
+
for key in mapping:
|
|
149
|
+
...
|
|
150
|
+
for value in mapping.values():
|
|
151
|
+
...
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Mutation vs Reassignment
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
# Mutation (changes object in place)
|
|
160
|
+
lst.append(x)
|
|
161
|
+
lst.extend(other)
|
|
162
|
+
lst[0] = new
|
|
163
|
+
dct[key] = value
|
|
164
|
+
s.add(item)
|
|
165
|
+
|
|
166
|
+
# Reassignment (binds name to new object)
|
|
167
|
+
lst = lst + [x] # New list
|
|
168
|
+
dct = {**dct, k: v} # New dict
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- Mutation affects all references to the object
|
|
172
|
+
- Reassignment only affects the local name
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Decision Rules
|
|
177
|
+
|
|
178
|
+
| Need | Structure |
|
|
179
|
+
|------|-----------|
|
|
180
|
+
| Ordered, mutable, duplicates | `list` |
|
|
181
|
+
| Ordered, immutable, hashable | `tuple` / `NamedTuple` |
|
|
182
|
+
| Key → value, fast lookup | `dict` |
|
|
183
|
+
| Unique items, membership test | `set` |
|
|
184
|
+
| Unique items, immutable | `frozenset` |
|
|
185
|
+
| Fixed schema, heterogeneous | `dataclass` / `NamedTuple` / `TypedDict` |
|
|
186
|
+
| Stack (LIFO) | `list` (append/pop) |
|
|
187
|
+
| Queue (FIFO) | `collections.deque` |
|
|
188
|
+
| Priority queue | `heapq` |
|
|
189
|
+
| Counter/multiset | `collections.Counter` |
|
|
190
|
+
| Default values for missing keys | `collections.defaultdict` |
|
|
191
|
+
| Ordered dict with LRU | `collections.OrderedDict` / `functools.lru_cache` |
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Preferred Patterns
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
# Use comprehensions for simple transformations
|
|
199
|
+
squares = [x*x for x in range(10)]
|
|
200
|
+
even_squares = {x*x for x in range(10) if x % 2 == 0}
|
|
201
|
+
name_to_len = {name: len(name) for name in names}
|
|
202
|
+
|
|
203
|
+
# Generator for large/unknown sequences
|
|
204
|
+
def generate_items():
|
|
205
|
+
for i in range(1_000_000):
|
|
206
|
+
yield compute(i)
|
|
207
|
+
|
|
208
|
+
# Defaultdict for grouping
|
|
209
|
+
from collections import defaultdict
|
|
210
|
+
grouped = defaultdict(list)
|
|
211
|
+
for item in items:
|
|
212
|
+
grouped[key(item)].append(item)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Avoid
|
|
218
|
+
|
|
219
|
+
- `list` for membership testing (O(n)) — use `set`
|
|
220
|
+
- `list` for queue (pop(0) is O(n)) — use `deque`
|
|
221
|
+
- Nested lists for matrices (use `numpy` or flat list)
|
|
222
|
+
- `dict` with mutable keys (unhashable)
|
|
223
|
+
- Modifying container during iteration (iterate over copy)
|
|
224
|
+
- Excessive nesting depth (>3 levels) — use dataclasses
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Validation Considerations
|
|
229
|
+
|
|
230
|
+
- Type checkers verify generic type parameters
|
|
231
|
+
- `collections.abc` interfaces for structural typing
|
|
232
|
+
- Mutation during iteration raises `RuntimeError`
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Related Skills
|
|
237
|
+
|
|
238
|
+
- `core/advanced_python.md` (generators, iterators)
|
|
239
|
+
- `stdlib/collections.md`
|
|
240
|
+
- `stdlib/itertools.md`
|
|
241
|
+
- `generation/type_hints.md` (generics)
|
|
242
|
+
- `core/comprehensions.md`
|
|
243
|
+
- `quality/duplication.md`
|