Skip to content

Commit 1a06009

Browse files
committed
tricks: add runnable idioms (unpacking, enumerate/zip, comprehensions, Counter, defaultdict, pathlib, lru_cache, dataclass, suppress, guarded 3.9/3.10)
1 parent d589704 commit 1a06009

File tree

1 file changed

+120
-1
lines changed

1 file changed

+120
-1
lines changed

python/tricks.py

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
2+
3+
from collections import Counter, defaultdict
4+
from contextlib import suppress
5+
from dataclasses import dataclass
6+
from functools import lru_cache
7+
from pathlib import Path
8+
import sys
9+
10+
from passed import passed
211

312
def multi_args(a, b, c,):
413
assert(a == 1)
@@ -13,3 +22,113 @@ def multi_args(a, b, c,):
1322
args = [ 1, 2, 3 ]
1423

1524
multi_args(*args)
25+
26+
27+
# Sequence unpacking with a starred target
28+
nums = [1, 2, 3, 4]
29+
first, *middle, last = nums
30+
assert first == 1 and middle == [2, 3] and last == 4
31+
32+
# Swap without a temp
33+
x, y = 10, 20
34+
x, y = y, x
35+
assert x == 20 and y == 10
36+
37+
# enumerate with a custom start
38+
letters = ["a", "b"]
39+
assert list(enumerate(letters, start=1)) == [(1, "a"), (2, "b")]
40+
41+
# zip and unzip
42+
names = ["alice", "bob"]
43+
scores = [3, 4]
44+
pairs = list(zip(names, scores))
45+
assert pairs == [("alice", 3), ("bob", 4)]
46+
unzipped_names, unzipped_scores = zip(*pairs)
47+
assert list(unzipped_names) == names and list(unzipped_scores) == scores
48+
49+
# Comprehensions
50+
squares = [n * n for n in range(5)]
51+
assert squares == [0, 1, 4, 9, 16]
52+
53+
codepoints = {c: ord(c) for c in "ab"}
54+
assert codepoints == {"a": 97, "b": 98}
55+
56+
parities = {n % 2 for n in range(5)}
57+
assert parities == {0, 1}
58+
59+
# any/all
60+
assert any([0, "", 3]) is True
61+
assert all([1, True, "x"]) is True
62+
63+
# Chained comparisons
64+
z = 5
65+
assert 1 < z < 10
66+
67+
# Slicing tricks
68+
s = "abcd"
69+
assert s[::-1] == "dcba"
70+
assert s[::2] == "ac"
71+
72+
# Join strings
73+
assert "-".join(["a", "b", "c"]) == "a-b-c"
74+
75+
# dict.get and setdefault
76+
lookup: dict[str, list[int]] = {}
77+
assert lookup.get("missing", 42) == 42
78+
lookup.setdefault("items", []).append(1)
79+
lookup.setdefault("items", []).append(2)
80+
assert lookup["items"] == [1, 2]
81+
82+
# defaultdict for grouping
83+
data = [("a", 1), ("b", 2), ("a", 3)]
84+
grouped: defaultdict[str, list[int]] = defaultdict(list)
85+
for key, value in data:
86+
grouped[key].append(value)
87+
assert grouped["a"] == [1, 3] and grouped["b"] == [2]
88+
89+
# Counter for frequencies
90+
cnt = Counter("abca")
91+
assert dict(cnt) == {"a": 2, "b": 1, "c": 1}
92+
93+
# pathlib basics
94+
assert Path(__file__).name == "tricks.py"
95+
96+
# lru_cache for memoization
97+
@lru_cache(maxsize=None)
98+
def fib(n: int) -> int:
99+
return n if n < 2 else fib(n - 1) + fib(n - 2)
100+
101+
assert fib(10) == 55
102+
103+
# dataclass for simple value objects
104+
@dataclass
105+
class Point:
106+
x: int
107+
y: int
108+
109+
110+
p1 = Point(1, 2)
111+
p2 = Point(1, 2)
112+
assert p1 == p2 and repr(p1).startswith("Point(")
113+
114+
# Context manager that ignores specific errors
115+
with suppress(ZeroDivisionError):
116+
1 / 0
117+
118+
# Guarded examples for newer syntax/features
119+
if sys.version_info >= (3, 9):
120+
d1 = {"a": 0, "b": 2}
121+
d2 = {"a": 1, "c": 3}
122+
merged = d1 | d2 # dict merge operator (3.9+)
123+
assert merged == {"a": 1, "b": 2, "c": 3}
124+
125+
if sys.version_info >= (3, 10):
126+
# Structural pattern matching (3.10+)
127+
match (1, 0):
128+
case (1, 0):
129+
matched = True
130+
case _:
131+
matched = False
132+
assert matched
133+
134+
passed()

0 commit comments

Comments
 (0)