【手を動かす道場】Python実戦10本ノック(データ加工・内包表記・自動化の必須パターン)

2026-11-06 / シリーズ「実戦コード・ノック道場」第3話 / Python, プログラミング, 内包表記, ハンズオン, 10本ノック, 初心者向け

「文法書を読んで基本は理解したはずなのに、実務でCSVデータやAPIのJSONを前にすると、どうコードを書いていいか手が止まる」 「ネットで見かけるスマートなPythonコードが、なぜあんなに短く書けるのか意味が分からない」

Pythonは「誰が書いても同じように読みやすい」ことを目指して作られた言語です。 しかし、多くの初学者が「初歩の文法」から「実務のコード」へとステップアップできずに挫折します。

その理由は明白です。 実務で求められるPythonの仕事の8割は、複雑なオブジェクト指向や数学アルゴリズムではなく、「乱雑なデータを、目的の形へとサクサク成形する(データスライシング・辞書操作・内包表記)」というデータの解体・再構築作業だからです。

しかも、Pythonのデータ構造には**「なぜ内包表記は通常のfor文より速いのか?」「なぜ辞書(dict)は数百万件あっても一瞬で値が見つかるのか?」**という、メモリとバイトコードの明確な物理理由が存在します。

この記事では環境構築は一切不要です。 背後にあるメモリ構造の物理を5分で掴んだら、ページ内の**「埋め込みPython道場」で実際にコードを書いて10本ノックを制覇**してください。


1. Pythonのメモリ物理:すべては「ポインタ(参照)」の海である

Pythonを真に理解するための最大の鍵は、**「Pythonの変数は、データを直接しまっている箱ではなく、メモリ上のオブジェクトを指し示す名札(参照/ポインタ)に過ぎない」**という事実です。

C言語の配列 vs Pythonのリスト

C言語などの静的言語の配列は、メモリ上に同じサイズのデータが隙間なくぎっしり並びます。 一方、Pythonのリスト(list)は、**「オブジェクトのアドレス(ポインタ)を並べた配列」**として実装されています(CPythonの PyListObject)。

リスト変数 numbers Index 0 ポインタ(参照) Index 1 ポインタ(参照) Index 2 ポインタ(参照) 整数オブジェクト: 10 型情報 + 参照カウント + 値 文字列オブジェクト: 'Tokyo' 型情報 + 参照カウント + 値 リストオブジェクト: [1, 2] 型情報 + 参照カウント + 値 本体は「ポインタの配列」だから異なる型を混在でき、インデックス計算は足し算だけで O(1)

この「ポインタの配列」という物理構造のおかげで、Pythonのリストは「整数、文字列、辞書」など異なる型のデータを何でも混在して放り込むことができます。 そして、インデックス指定(numbers[2])によるアクセスは、「先頭アドレス + 2 × ポインタサイズ」という単純な足し算で一瞬で計算できるため、要素数が1億個あっても$O(1)$(定数時間)の超高速でアクセスできます。

なぜ内包表記は for ループ+append() より速いのか?

実務のコードで、誰もがこぞって [x * 2 for x in data] という「内包表記」を使うのには、コードが短くなること以上に物理的な実行速度の差があります。

# パターンA: 通常のforループ
result = []
for x in data:
    result.append(x * 2)

# パターンB: リスト内包表記
result = [x * 2 for x in data]
  1. 通常のforループ(パターンA): ループが1回回るたびに、Python仮想マシン(PVM)は「result から append という属性を探し(属性探索)」、「それを関数として呼び出す(関数呼出のスタック積層)」という重いステップを何万回も繰り返します。
  2. リスト内包表記(パターンB): 内包表記は、Pythonのバイトコードレベルで**専用の最適化命令(LIST_APPEND)**として解釈されます。属性探索も関数呼び出しのオーバーヘッドもすべてバイパスし、C言語レベルのループで直接メモリ領域に値を書き込んでいくため、実行速度が20%〜40%以上も高速になります。

短く書ける構文は、コンピュータにとっても無駄がない。これがPythonの洗練された物理です。

触って試す:for文を1行ずつ実行してみる(ステップ実行)

🐍 ステップ実行:合計を求めるプログラム

「次へ」ボタンを押すたびに、プログラムが1行ずつ進みます。変数の中身と出力がどう変わるかを目で追ってください。次の「10本ノック道場」に入る前に、実行の流れを掴むウォーミングアップです。

出力:


2. 辞書(dict)の奇跡:ハッシュテーブルと $O(1)$ 探索

実務でリスト以上に使い倒すのが、キーと値のペアを管理する**「辞書(dict)」**です。 なぜ、辞書は100万人の社員データの中から、社員番号を指定した瞬間に0.00001秒で目的のデータを引き当てられるのでしょうか?

その秘密は、内部で動く**「ハッシュ関数(Hash Function)」**にあります。

🔑 キー: 'emp_1042' 🧮 ハッシュ関数 hash() で変換 → ハッシュ値: 8392174829 ➗ 配列サイズで割った「余り」 → インデックス番号: 6 🎯 一撃でその番地へ! バケット 6: {'emp_1042': '田中陽平'}

辞書は、データを先頭から1件ずつ探す(線形探索:$O(N)$)ような泥臭いことはしません。

  1. キーの文字列('emp_1042')をハッシュ関数に通し、巨大な一意の整数値へ変換する。
  2. その数値を配列のサイズで割った「余り」を、配列のインデックス番号とする。
  3. 最初からそのインデックス番号のメモリ番地を目掛けてピンポイントで飛ぶ。

データが10件だろうが100万件だろうが、目的のデータへアクセスする手間は「1回のハッシュ計算」で終わり、計算量は常に**$O(1)$**です。 実務で「データの検索・突き合わせ」を行うときに、リストのループではなく辞書や集合(set)を使うべき絶対の物理的理由がここにあります。


3. 【実践】ブラウザ内完結・Python実戦10本ノック道場

下のボックスは、あなたのブラウザ内で完全に動作する**「Python実行&自動採点環境」**です。 実務で最も頻出する10の課題を用意しました。

問題を読み、エディタにPythonコードを入力して**「▶ Pythonコードを実行&採点」**ボタンを押してください(Ctrl + Enter でも実行可能です)。

PYTHON ESSENTIALS DOJO 全10問・実戦データ加工演習
クリア状況: 0 / 10 問
▼ 出力コンソール (標準出力 stdout)
まだ実行されていません。

4. 全10本ノックの「急所」と模範解答・現場の掟

道場で手を動かしたあとに読むことで、業務コードを劇的に美しく堅牢にする「Pythonイディオムの真髄」を完全インストールします。

第1問〜第2問:データの安全な切り出しと取得

【Q1】スライスの極意([start:stop:step])

sales = [120, 450, 300, 720, 510, 680, 890]
print(sales[-3:])  # [510, 680, 890]

【Q2】辞書から安全に取り出す(dict.get())

user = {'name': '加藤', 'role': 'admin'}
print(user.get('email', 'not_set'))  # not_set

第3問〜第4問:内包表記による高速データ変換

【Q3・Q4】リスト内包表記と辞書内包表記

# リスト内包表記
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
result = [x**2 for x in numbers if x % 2 == 0]

# 辞書内包表記
prices = {'リンゴ': 120, 'バナナ': 80, 'メロン': 1500, 'ミカン': 60}
result = {k: v for k, v in prices.items() if v >= 100}
for x in numbers 1. 元データを回す if x % 2 == 0 2. 条件で絞り込む x ** 2 3. 加工して格納する

第5問〜第6問:文字列の成形と可視化

【Q5】文字列の分解(.split())と結合(.join())

raw_data = 'server01,192.168.1.10,online,Tokyo'
parts = raw_data.split(',')
print('-'.join(parts))

【Q6】f-strings(フォーマット文字列)の威力

item = 'GPUサーバー'
price = 2400000
print(f'品目: {item} / 価格: {price:,}円')

第7問〜第10問:実務の泥臭い自動化パターン

【Q7】2つのリストをペアで回す(zip())

names = ['佐藤', '鈴木', '高橋']
scores = [85, 92, 78]
for name, score in zip(names, scores):
    print(f'{name}: {score}点')

【Q8】カスタムソート(sorted() と lambda)

members = [{'name': 'A', 'age': 32}, {'name': 'B', 'age': 25}, {'name': 'C', 'age': 45}]
print(sorted(members, key=lambda x: x['age']))

【Q9】集計辞書パターンの黄金律

records = [('営業部', 100), ('開発部', 150), ('営業部', 80), ('総務部', 60), ('開発部', 200)]
total = {}
for dept, amount in records:
    total[dept] = total.get(dept, 0) + amount

【Q10】例外処理によるデータクリーニング(try - except)

raw_nums = ['100', '250', 'error', '400', 'N/A', '150']
total = 0
for item in raw_nums:
    try:
        total += int(item)
    except ValueError:
        pass

結論:Pythonとは「データ構造を最短で流すパイプ」である

Pythonを使いこなすとは、難しいライブラリを何十個も覚えることではありません。 現実世界の汚れたデータを、

  1. スライスや .split() で分解し、
  2. リスト内包表記で研ぎ澄まし、
  3. 辞書のハッシュ構造($O(1)$)に流し込んで集計する。

この一連の「データの解体と再構築」が手癖になったとき、Excelで何時間もかかっていた手作業や、APIから降ってくる巨大なJSONの解析は、わずか数十行のスクリプトによって数秒で自動化されるようになります。

指先に刻んだ10の型を武器に、明日の実務コードを美しく書き換えてください。


📝 3行で頭に入る『試験・実務・投資の要点まとめ』

  1. 【メモリの物理】 リストはポインタの連続配列のため $O(1)$ でアクセスでき、辞書はハッシュ関数によりデータ量に関わらず $O(1)$ の超高速でキーを探索する。
  2. 【内包表記の最適化】 内包表記が通常の for より速いのは、属性探索や関数呼出をスキップしてC言語レベルの最適化命令 LIST_APPEND を直接叩くため。
  3. 【実務の防御策】 未知のデータには dict.get('key', default) や try - except ValueError を使い、KeyErrorや異常値によるクラッシュを最小の手間で防ぐのがプロの鉄則。

確認クイズ

📝 確認クイズ(3問)