はじめに
現場で「知ってるだけで速くなる・ミスが減る」系の Python 小技を 10 個、コピペできる形でまとめました。
基本的なものから少しマニアックなものまで、Before → After 形式を交えて紹介します。
対象:Python 3.10 以上(一部 3.8+ で動作)
ループ編
1. enumerate() ― index 管理を捨てる
Before
for i in range(len(items)):
print(i, items[i])
After
for i, x in enumerate(items, start=1):
print(i, x)
range(len(...)) + 添字アクセスは、off-by-one の温床です。
enumerate() なら index と要素がセットで手に入るので、ズレようがありません。
2. zip() ― 複数リストを安全に並走
for name, score in zip(names, scores):
print(name, score)
Python 3.10 以降なら strict=True が使えます。
for name, score in zip(names, scores, strict=True):
print(name, score)
# リストの長さが違うと即 ValueError → サイレントなデータ欠損を防げる
長さが違うことを許容したい場面では itertools.zip_longest() を使いましょう。
3. next() ― 最初の 1 件だけ欲しいときにループしない
Before
first = None
for x in items:
if x.active:
first = x
break
After
first = next((x for x in items if x.active), None)
「見つかったら break」のパターンを 1 行にできます。
第 2 引数にデフォルト値を渡せるので、見つからなかったときの None チェックも自然に書けます。
データ構造編
4. dict.get() / setdefault() ― 分岐を減らす
Before
if x in count:
count[x] += 1
else:
count[x] = 1
After
count[x] = count.get(x, 0) + 1
setdefault() を使えば、初期化と追加を同時にできます。
d.setdefault(key, []).append(value)
「キーが存在するか確認して……」の if/else が消えるだけで、コードの見通しが一気に良くなります。
5. collections.Counter ― 集計は最短で
from collections import Counter
c = Counter(words)
print(c.most_common(5))
頻度集計はだいたいこれで終わります。
辞書を回して手動カウントしていたら、まず Counter を疑ってください。
ファイル・パス編
6. pathlib.Path ― パス操作はオブジェクトで
from pathlib import Path
p = Path("logs") / "app.log"
text = p.read_text(encoding="utf-8")
p.write_text("hello\n", encoding="utf-8")
os.path.join() + open() の組み合わせと比べて、OS 差分(\ vs /)や結合ミスが激減します。
p.stem, p.suffix, p.parent など、属性アクセスだけで欲しい情報が取れるのも強みです。
7. contextlib.suppress() ― 「握りつぶしていい例外」を明示する
with 文でリソースを閉じるのは基本中の基本ですが、もう一歩踏み込んでみましょう。
Before
try:
os.remove("tmp.txt")
except FileNotFoundError:
pass
After
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove("tmp.txt")
「この例外は無視して OK」という 意図 がコードに残ります。
空の except: pass と違い、握りつぶす対象が限定されるので安全性も上がります。
式・構文編
8. 代入式(ウォルラス演算子):= ― 一度だけ計算して if へ
if (n := len(data)) > 100:
print("big", n)
「同じ関数を 2 回呼ぶ」事故が減ります。
while ループでの利用も便利です。
while chunk := f.read(8192):
process(chunk)
※ Python 3.8 以上で使えます。
9. sorted(..., key=...) ― 複雑なソートは key 関数で勝つ
users_sorted = sorted(users, key=lambda u: (u.age, u.name))
タプルを返せば 複数キーでのソート が簡単に書けます。
「降順 + 昇順」の混在も、数値なら - を付けるだけ。
# age は降順、name は昇順
sorted(users, key=lambda u: (-u.age, u.name))
比較関数を自作するより事故りにくく、意図も伝わりやすいです。
10. f-string(デバッグ向け =)
x = 12
y = 3.4567
print(f"{x=}, {y=:.2f}") # x=12, y=3.46
= を付けるだけで 変数名と値がセットで出力 されます。
print("x:", x, "y:", y) と書く時代は終わりました。ログやデバッグが格段に速くなります。
※
=記法は Python 3.8 以上で使えます。
まとめ
| # | 小技 | 一言効果 |
|---|---|---|
| 1 | enumerate() |
index の手動管理を排除 |
| 2 |
zip() + strict=True
|
長さ不一致のサイレント欠損を防止 |
| 3 |
next() + ジェネレータ式 |
「最初の 1 件」をワンライナーに |
| 4 |
dict.get() / setdefault()
|
キー存在チェックの if/else を削減 |
| 5 | Counter |
頻度集計を 2 行で完了 |
| 6 | pathlib.Path |
パス結合・読み書きをオブジェクトで安全に |
| 7 | contextlib.suppress() |
無視していい例外を明示的に宣言 |
| 8 |
:=(ウォルラス演算子) |
同じ計算の 2 回呼びを防止 |
| 9 | sorted(key=...) |
複数キーソートをタプルで簡潔に |
| 10 | f-string =
|
デバッグ出力を一瞬で |
どれも「知ってるか知らないか」だけの差ですが、積み重なると コードの読みやすさ・安全性・スピード に大きく効いてきます。
気になるものがあれば、ぜひ今日のコードから 1 つ試してみてください。