
外部ライブラリを増やさずに、コードの品質と保守性をグッと上げたい…。
標準ライブラリ“だけ”で、どこまで実務が回せる?
今回はそんな悩みを解決するために、Python標準ライブラリの“珠玉の10選”を、実務でそのまま使えるチートシート+コピペコードでまとめます。口調や見栄えはLightGBM記事と同じトーンでお届けします。
この記事で身に付く力
- 外部依存を最小に抑えた実務コード設計
- datetime/pathlib/itertools…など10モジュールの即戦力パターン
- アンチパターン→標準での改善手順
結論:標準ライブラリだけで実務はかなり進む
特に、(1) 日時/タイムゾーン(datetime/zoneinfo
)、(2) ファイルとパス(pathlib
)、(3) イテレータの道具箱(itertools
)、(4) 集計/バッファ(collections
)、(5) キャッシュ/部分適用/汎用化(functools
)、(6) 軽量統計(statistics
)、(7) データモデル(dataclasses
)、(8) 型ヒント(typing
)、(9) テキスト抽出(re
)、(10) 上位K/二分探索(heapq/bisect
)は“即効性”が高いです。この記事では現場で一番おいしい所だけを抜き出して解説します。
外部ライブラリ過多が生む3つの負債
実務では便利さの裏にコストが潜みます。私の経験上、外部依存をむやみに増やすと次の負債が膨らみがちです。
- 依存が増える:破壊的変更や脆弱性対応で保守コストが膨張。
- 配布が重い:社内配布/オフライン実行で環境が壊れやすい。
- 学習が分散:同じ課題なのに似た外部依存を覚える手間。
だからこそ、まずは標準ライブラリ。それで足りない所だけ外部に頼る、が長期的に安定します。
現場10年で残った「定番セット」
100件以上の案件で、私はまず標準で組む→最小限だけ外部の順に統一。結果、事故率が目に見えて減りました。以下の10選は、副業/在宅×実務の現場で本当に効いたパターンだけを抽出しています。
珠玉の10選(コピペOKのチートシート)
1) datetime
/ zoneinfo
:タイムゾーン安全な日時管理
“常にtz-awareで扱い、保存はISO8601”が鉄則。夏時間のある地域ではzoneinfo
が必須です。
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo # Python 3.9+
JST = ZoneInfo("Asia/Tokyo")
UTC = ZoneInfo("UTC")
# 取得:常に tz-aware
now\_jst = datetime.now(JST)
# 変換:UTCへ→ISO8601で保存
now\_utc = now\_jst.astimezone(UTC)
iso = now\_utc.isoformat()
# 解析:ISOなら fromisoformat、その他は strptime
parsed = datetime.fromisoformat("2025-09-01T12:00:00+09:00")
naive = datetime.strptime("2025/09/01 12:00", "%Y/%m/%d %H:%M").replace(tzinfo=JST)
# 範囲生成(週次レポート)
start = datetime(2025, 8, 1, tzinfo=JST)
end = datetime(2025, 9, 1, tzinfo=JST)
cur = start
while cur < end:
print(cur.date())
cur += timedelta(days=7)
ミスりやすい点:naiveなdatetime
と混在させない。保存はisoformat()
で。
2) pathlib
:OS非依存のパス/入出力
os.path
の手書き連結は卒業。Path
の/
演算子で安全で読みやすいコードに。
from pathlib import Path
root = Path("data")
# 作成/列挙/読み書き
(root / "out").mkdir(parents=True, exist\_ok=True)
for p in root.glob("\*.csv"):
text = p.read\_text(encoding="utf-8")
(root / "out" / p.name).write\_text(text, encoding="utf-8")
# 原子置換は:一時ファイルで書いてから置き換える(詳しくは「ファイル操作(307)」を参照)
現場メモ(ふみと):昔os.path.join
に\\
//
が混ざってWindowsで崩壊…Path
に置き換えてから消滅しました。
3) itertools
:速い“イテレータ部品”
巨大ファイルでも先頭だけ見る、複数シーケンスの直列結合、グルーピング…itertools
は“必要十分”の最短距離。
from itertools import islice, chain, groupby
# 先頭N件だけ(大きいファイルでも安全)
first10 = list(islice(range(1\_000\_000), 10))
# 2シーケンスを直列結合
merged = list(chain(\[1, 2], \[3, 4]))
# 事前に key でソート → groupby
rows = sorted(\[
{"store": "A", "qty": 2}, {"store": "B", "qty": 1}, {"store": "A", "qty": 5}
], key=lambda r: r\["store"])
for k, g in groupby(rows, key=lambda r: r\["store"]):
total = sum(r\["qty"] for r in g)
print(k, total)
# 小技:3.10+ の pairwise で隣接差分、accumulate で累積和
4) collections
:Counter
/ defaultdict
/ deque
/ namedtuple
軽い集計・バッファ・レコード表現はこれで十分。重い集計はpandasへパス。
from collections import Counter, defaultdict, deque, namedtuple
# カウント
c = Counter(\["A", "B", "A"]).most\_common(1) # \[('A', 2)]
# 集計(0初期化不要)
sum\_by = defaultdict(int)
for s, v in \[("A", 10), ("A", 3), ("B", 5)]:
sum\_by\[s] += v
# 直近N件のスライディング
buf = deque(maxlen=3)
for x in \[1, 2, 3, 4]:
buf.append(x)
print(list(buf)) # \[2, 3, 4]
# 名前付きの軽量レコード
Point = namedtuple("Point", "x y")
p = Point(2, 5)
print(p.x) # 2
注意:本格的な集計はpandasを使う方が速い→[内部リンク:pandas基礎]
5) functools
:キャッシュ/部分適用/汎用化
純粋関数にはlru_cache
。入出力(HTTP/DB)はキャッシュ対象外にするのが原則です。
from functools import lru_cache, partial, singledispatch
from math import floor
@lru\_cache(maxsize=1024)
def fib(n: int) -> int:
return n if n < 2 else fib(n-1) + fib(n-2)
# 部分適用(割引率を固定)
def discount(price, rate):
return floor(price \* (1 - rate))
bf = partial(discount, rate=0.3)
# 型ごとに処理を切替(軽い多相)
@singledispatch
def dump(x):
return str(x)
@dump.register(list)
def \_(x: list):
return ",".join(map(str, x))
6) statistics
:軽量統計(平均/分位/相関)
前処理の検算に最適。重い統計はnumpy/pandas/scipy
に任せましょう。
from statistics import mean, median, quantiles, pstdev, stdev, correlation
xs = \[1, 2, 3, 4, 5]
print(mean(xs), median(xs), quantiles(xs, n=4)) # 3 3 \[2.0, 3.0, 4.0]
# 分散の母/標本に注意
print(pstdev(xs), stdev(xs)) # 母標準偏差 / 標本標準偏差
# 相関(3.10+)
ys = \[2, 4, 6, 8, 10]
print(correlation(xs, ys)) # ほぼ1.0
7) dataclasses
:データモデルを簡潔&型安全に
辞書の“野良キー”を撲滅。default_factory
で可変デフォルトの罠も回避できます。
from dataclasses import dataclass, field
from datetime import date
from typing import Iterable
@dataclass(frozen=True)
class Order:
id: int
price: int
created: date
tags: list\[str] = field(default\_factory=list)
def total(orders: Iterable\[Order]) -> int:
return sum(o.price for o in orders)
8) typing
:意図を型で固定してレビューを楽に
API入出力にはTypedDict
、分岐の固定にはLiteral
、DIにはProtocol
が便利。
from typing import TypedDict, Literal, Optional, Protocol
class User(TypedDict):
id: int
name: str
role: Literal\["admin", "staff"]
class Notifier(Protocol):
def send(self, msg: str) -> None: ...
def greet(u: User, notifier: Notifier, prefix: Optional\[str] = None) -> None:
pre = prefix or "Hello"
notifier.send(f"{pre}, {u\['name']}")
9) re
:高速・簡潔なテキスト抽出
パターンは散らさず関数化+テストへ。名前付きグループや先読み/後読みで可読性UP。
import re
text = "id=42, price=1,234円"
# 名前付きグループ+先読み/後読み
m = re.search(r"id=(?P\\d+),\s\*price=(?P\\[\d,]+)円", text)
if m:
id\_ = int(m.group("id"))
price = int(m.group("price").replace(",", ""))
# コンパイル+フラグ
pat = re.compile(r"^\w+@\w+.\w+$", flags=re.IGNORECASE)
assert pat.match("[USER@EXAMPLE.com](mailto:USER@EXAMPLE.com)")
10) heapq
/ bisect
:上位Kと二分探索でO(log n)
リアルタイム上位Kやスケジューラ、ソート済み配列の挿入位置探索に。
import heapq, bisect
# 上位K(大きい順3件)
xs = \[5, 1, 9, 3, 7]
print(heapq.nlargest(3, xs)) # \[9, 7, 5]
# 優先度付きキュー(最小ヒープ)
h = \[]
heapq.heappush(h, (1, "low"))
heapq.heappush(h, (0, "urgent"))
prio, item = heapq.heappop(h) # (0, 'urgent')
# ソート済みリストへの挿入位置(重複は右側)
arr = \[10, 20, 20, 30]
idx = bisect.bisect\_right(arr, 20) # 3
arr.insert(idx, 20) # \[10, 20, 20, 20, 30]
アンチパターン → 標準で直す
- 文字列の
+
連結ループ →"".join(list)
/io.StringIO
os.path
の手書き →pathlib
- 自作のキャッシュ辞書 →
lru_cache
- 手書きのトップK →
heapq.nlargest
- 自作型チェック →
typing
のProtocol/Literal/TypedDict
用途別の“最小レシピ”
- 週次PDFレポート:
datetime/zoneinfo
で範囲→pandas
で集計→xlsxwriter
でExcel→[内部リンク:データ可視化レポート納品の型] - ログ加工:
pathlib.glob
→itertools.islice/chain
→re
で抽出→statistics
で検算 - API連携:
dataclasses
でモデル→typing
で型→functools
のDI/partialで注入→[内部リンク:API入門]
今日やること(45分)
os.path
/自作TopK/自作キャッシュをpathlib/heapq/lru_cache
に置換zoneinfo
を導入してISO8601保存に統一dataclasses
で1つデータモデル化し、TypedDict
→dataclass変換を作成re
の生パターンを関数化+pytestで1件守る
伴走:標準ライブラリ優先の“軽い実務設計”を導入
無料カウンセリング/体験で、あなたのスクリプトに標準ライブラリ中心の設計(datetime/pathlib/itertools/...
)を導入し、依存削減×再現性UPの構成に整えます。
TechAcademy データサイエンスコース(受講料:174,600円~ ※更に割引あり)

株式会社キカガク AI人材長期育成コース(受講料:237,600円~)

次に読む(内部リンク)
-
-
もう事故らせない:PythonでCSV/JSON/Excelを安全に読み書きする実務レシピ
CSV/JSON/Excelの読み書き、どこから気をつければいい? 文字化け・先頭ゼロ欠落・壊れたExcel……もう事故らせたくない! 結論:データ仕事の9割はI/O(入出力)。ここを整えるだけで、桁 ...
-
-
Python実務の型:例外処理と構造化ログでエラーに強いコードを書く
例外処理って、結局どこまでやれば“実務で困らない”の? ログも整えるのって大変そう…最低限の型、ください! この記事は、pythonbunseki.comの実務トーンで「防ぐ→気づく→復旧する」をコー ...
-
-
Python関数とスコープの設計術:I/O分離×型ヒントで再利用性とテスト容易性を最大化
関数がどんどん太ってテストしづらい…どう整理すればいい? globalやprintが混ざっていて、ユニットテストを書く気力が出ない… この記事では、関数とスコープの設計を“純度×境界×型”の視点で整え ...
-
-
自動化:スケジューリングと業務改善の型|「再実行安全×観測可能×静かに動く」を仕組みにする
夜中に動かしているPython、自動で止まってた…ログもなくて原因が追えない…。 「毎朝のレポート」や「在庫監視」を、壊れず静かに回したい…! 業務で落ちない自動化を作る鍵は、(1) 再実行安全(Id ...
-
-
API入門:OpenAPI/HTTPの基本と“壊れない”Pythonクライアント設計(コピペOK)
API連携を始めたいけど、何から学べば“壊れない仕組み”になる? OpenAPI?HTTP?タイムアウト?……用語が多すぎて迷子になりがち。 本記事は、HTTPの基礎×OpenAPIの読み方×堅牢なク ...
最近のコメント