Pythonの「なるほど!」と思えるユニークな機能①

こんにちは。ゆうせいです。

「f-string」や「スライス[::-1]」など、Pythonの“魔法”のような記法に、すっかり魅了されてしまったようですね!

「どうしてこんな便利なものがあるんだ!」と知ったときの喜びは、プログラミング学習の最高のご褒美の一つです。

さて、皆さんは for ループを書くとき、こんな「ちょっと面倒くさいな…」と思うことはありませんか?

  • 「今、ループの何回目か?」を知るために、別でカウンター変数(i = 0)を管理している。
  • 二つのリストを同時に処理したいけど、どうやって回せばいいか悩む。

これらの「あるある」な悩みを、Pythonは驚くほどスマートに解決してくれます。

今回は、そんな「ループの達人」になるための2つの関数と、安全なファイル操作の「お作法」について学んでいきましょう!


特徴1: ループの「回数」と「中身」を同時にゲット! enumerate

リストの要素を処理しながら、「これは0番目、これは1番目…」とインデックス番号(添字)も一緒に使いたい時、ありますよね。

enumerate を知らない場合:

range(len(list)) を使ったり、カウンター変数を用意したり…ちょっとダサい感じがします。

fruits = ["apple", "banana", "cherry"]
index = 0
for fruit in fruits:
    print(f"{index}番目のフルーツは {fruit} です")
    index += 1

これを、Pythonの enumerate (イニューメレイト)関数は一発で解決します。

enumerate を使った場合:


実行結果:

0番目のフルーツは apple です
1番目のフルーツは banana です
2番目のフルーツは cherry です

for index, fruit in enumerate(fruits): と書くだけで、fruits リストから「インデックス番号」と「要素そのもの」を同時に、順番に取り出してくれているんです!

専門用語解説: enumerate 関数

enumerate は「列挙する」という意味の英単語です。

例えるなら、「自動で番号札を配ってくれる受付係」です。

for ループがリスト(fruits)から「apple さん、どうぞ」と要素を取り出そうとすると、enumerate 受付係がすかさず「apple さんは 0番 ですね」と番号札(index)を一緒に渡してくれるイメージです。

range(len(...)) のような無骨な書き方をしなくて済む、非常にPythonicな関数ですよ!


特徴2: 複数のリストを「同時に」回る! zip

次に、二つ(以上)のリストを、並行して処理したいケースです。

例えば、students(生徒名リスト)と scores(点数リスト)があり、"Aさんは 80点" のように組み合わせて表示したいとします。

zip を知らない場合:

インデックス番号を使って、それぞれのリストから無理やり取り出すことになります。

students = ["Aさん", "Bさん", "Cさん"]
scores = [80, 92, 75]
for i in range(len(students)):
    print(f"{students[i]} は {scores[i]}点")

これでは読みにくいですし、リストの長さが違ったらエラーになる危険もあります。

ここで「zip (ジップ)」関数の出番です!

zip を使った場合:

students = ["Aさん", "Bさん", "Cさん"]
scores = [80, 92, 75]
for student, score in zip(students, scores):
    print(f"{student} は {score}点")

実行結果:

Aさん は 80点
Bさん は 92点
Cさん は 75点

zip(students, scores) と書くだけで、students から Aさん、scores から 80 を取り出してペアにしてくれます。

for student, score in ... の部分で、そのペアを student と score にアンパッキング(荷解き)して受け取っているんですね。

専門用語解説: zip 関数

zip は「ジッパー(ファスナー)」のことです。

洋服のジッパーが、左右のギザギザを順番にカチッ、カチッと噛み合わせていく様子を想像してください。

zip 関数はまさにあのイメージで、複数のリスト(studentsscores)の同じ順番にある要素を、("Aさん", 80), ("Bさん", 92) のようにペア(タプル)にしてくれるんです。

ちなみに、リストの長さが違う場合、zip短い方のリストが終わった時点で処理を安全に終了してくれます。賢いですね!


特徴3: 「後片付け」を自動化する with

最後は、ループとは少し違いますが、Pythonの「安全性」と「エレガンス」を象徴する機能です。

ファイルを開いて何かを書き込んだり、読み込んだりするとき、「開いたら、必ず閉じる」のがプログラミングのお作法です。

もし閉じ忘れると、OSのリソースを無駄遣いしたり、最悪の場合ファイルが壊れたりする可能性もゼロではありません。

with を知らない場合:

try...finally という構文を使って、「何が何でも(エラーが起きても)close() を実行する」という処理を書く必要がありました。

try:
    f = open("my_file.txt", "w") # 'w' = 書き込みモード
    f.write("Hello, Python!")
finally:
    f.close() # エラーがあっても、なくても、必ず実行される

これは面倒ですし、f.close() を書き忘れがちですよね。

そこでPythonは「with文」を用意しました。

with を使った場合:

with open("my_file.txt", "w") as f:
    f.write("Hello, Python!")
# (withブロックを抜けると、ここで自動的に f.close() が呼ばれる)

たったこれだけです!

with文のブロック(インデントされている範囲)を抜けさえすれば、Pythonが自動的にファイルの後片付け(f.close())をやってくれるんです。

専門用語解説: with 文 (コンテキストマネージャ)

with文は、専門用語で「コンテキストマネージャ」という仕組みを利用しています。

例えるなら、「時間制のレンタルスペース」です。

with open(...) as f: は、「(f という名前で)レンタルスペースに入室します」という宣言です。

そして、with のブロック内で作業(f.write(...))をします。

作業が終わり、ブロックを抜ける(=退室する)と、受付係(Python)が自動で「電気を消して、鍵を閉める(close())」という後片付けをすべてやってくれる、というイメージです。

途中でエラー(火事)が起きても、受付係が強制的に鍵を閉めて(close())くれるので、非常に安全です。

ファイル操作だけでなく、データベース接続やネットワーク通信など、「後片付け」が必要なあらゆる場面で活躍する、Pythonの「安全装置」なんです!


まとめと今後の学習指針

今回は、コードの「面倒くささ」や「危険性」を解消してくれる、賢い3つの特徴を見てきました。

  1. enumerate: for ループでインデックス番号を自動で付けてくれる!
  2. zip: 複数のリストをペアにして、同時に for ループで回せる!
  3. with 文: open() などの「後片付け(close())」を自動化し、安全にしてくれる!

enumerate と zip は、for文 を書く際の強力な武器になります。

with文 は、ファイルなどを扱う際の「標準的なお作法」です。

これらの書き方を知っていると、無駄なカウンター変数を定義したり、close() を書き忘れたりするミスが減り、コードが格段に読みやすく、安全になります。

Pythonには、collectionsモジュール(defaultdict など)や itertoolsモジュールなど、こうした「かゆいところに手が届く」道具がまだまだたくさん詰まった「道具箱」があります。

ぜひ、標準ライブラリの道具箱も覗いてみてくださいね!

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。