【未経験から始めるPython基礎⑥】sort() と lambda、型ヒントまで一気に理解しよう

5 min 62 views
Pythonの基礎⑥

Pythonを学び始めると、

  • リストの並び替え(sort())
  • 無名関数(lambda)
  • 型ヒント(x: str みたいな書き方)

といった「ちょっと難しそうに見える書き方」が急に出てきて、
モヤッとしがちです。

この記事では、次の2つのコード例を題材にしながら、

  1. sort(key=…) でリストを並び替える仕組み
  2. lambda の役割
  3. 型ヒントと __annotations__ の見え方

を、最初から順番にわかりやすく整理していきます。

1. まずは「リストの並び替え」からスタート

最初の例はこちらのコードです。

vegetables = ["cabbage", "leek", "tomato", "asparagus"]
vegetables.sort(key=lambda s: len(s))
print(vegetables)

 1-1. このコードでやりたいこと

やりたいのはとてもシンプルで、野菜の名前が入ったリストを「文字数の短い順」に並べたいというだけです。

元のリストはこちら:

  • "cabbage"(7文字)
  • "leek"(4文字)
  • "tomato"(6文字)
  • "asparagus"(9文字)

これを「文字数の短い順」に並べ替えます。

 1-2. sort() は「並び替えメソッド」

vegetables.sort(...)

sort()リストをその場で並び替えるメソッド です。
引数を何もつけないと、文字列の場合は 辞書順(アルファベット順) になります。

vegetables.sort()
# ['asparagus', 'cabbage', 'leek', 'tomato'] みたいな感じ

今回は「辞書順」ではなく「文字数」で並び替えたいので、key= というオプションを使います。

 1-3. key= は「何を基準に並び替える?」を決める

vegetables.sort(key=lambda s: len(s))

ここがポイントです。

  • key= には「並び替えの基準になる値を返す関数」を渡します。
  • 今回の lambda s: len(s) は、
    「文字列 s を受け取って、その長さ len(s) を返す関数」です。

つまりこの1行は、各要素の「文字数」を基準にして、短いものから順に並び替えてねという意味になります。

 1-4. 結果はどうなる?

「文字数の少ない順」に並ぶので、順番はこうなります。

  1. "leek"(4文字)
  2. "tomato"(6文字)
  3. "cabbage"(7文字)
  4. "asparagus"(9文字)

実際の出力:

['leek', 'tomato', 'cabbage', 'asparagus']

 1-5. 逆順にしたいとき

「長い順」にしたい場合は reverse=True をつけます。

vegetables.sort(key=lambda s: len(s), reverse=True)

これで 文字数が多いものから順 に並びます。

2. lambda ってなに者?簡単におさらい

ここまでで「lambda が出てくると急にむずかしそうに見える…」と感じたかもしれません。

lambda s: len(s)

これは一言でいうと、その場でサクッと作る「小さな関数」です。

同じことを普通の関数で書くと、こんな感じになります。

def length(s):
    return len(s)

vegetables.sort(key=length)

これと、

vegetables.sort(key=lambda s: len(s))

は、やっていることはまったく同じです。

  • わざわざ関数に名前をつけるほどでもない
  • その場で 1 回しか使わない

そんな場面で lambda がよく使われます。

3. 次のステップ:「型ヒント」と __annotations__ に触れてみよう

続いて、2つ目の例題です。

def func(x: str, y: str) -> str:
    print(func.__annotations__)
    return x + "," + y


print(func("Hello", "World"))

今度は、型ヒント(type hint)アノテーション情報 が登場します。

 3-1. 引数・戻り値の型ヒントとは?

def func(x: str, y: str) -> str:

この書き方は、Pythonの「型ヒント」という機能を使っています。

  • x: str → x は文字列を想定しています
  • y: str → y も文字列を想定しています
  • -> str → この関数は「文字列」を返すつもりです

ここで大事なのは、Pythonは型ヒントを書いても「実行時には強制しない」という点です。
これはあくまで「人間やツール(エディタ・型チェッカー)にとってのヒント」です。

 3-2. 関数本体の処理

return x + "," + y

ここはシンプルです。

  • 引数 x と y の間に , を挟んで文字列を連結しています。
  • “Hello” と “World” を渡しているので、結果は “Hello,World” になります。

 3-3. __annotations__ で型ヒントの中身を覗く

print(func.__annotations__)

ここが少しユニークなポイントですね。

func.__annotations__ は、関数につけた型ヒントを辞書(dict)の形で保持している属性です。

この例の場合、実際には次のような内容になります。

{'x': <class 'str'>, 'y': <class 'str'>, 'return': <class 'str'>}

つまり、

  • 引数 x の型 → str
  • 引数 y の型 → str
  • 戻り値(キー名 'return')→ str

という情報が丸ごと保存されていて、それをそのまま表示しているイメージです。

 3-4. 実行するとどう表示される?

print(func("Hello", "World"))

この1行が実行されると、流れはこうなります。

  1. func("Hello", "World") を呼び出し
  2. 関数内の print(func.__annotations__) が実行される
  3. {'x': <class 'str'>, 'y': <class 'str'>, 'return': <class 'str'>} が表示される
  4. return x + "," + y によって "Hello,World" が返ってくる
  5. 外側の print(...) によって "Hello,World" が表示される

最終的な出力は次の2行になります。

{'x': <class 'str'>, 'y': <class 'str'>, 'return': <class 'str'>}
Hello,World

4. 2つの例題から見えてくる「Pythonらしさ」

ここまで見てきた2つの例には、共通するポイントがあります。

 4-1. 「関数」を小さく・柔らかく使う文化

  • lambda でその場の小さな関数を定義する
  • 型ヒントをつけて、人にとって読みやすいコード にする
  • __annotations__ を見ることで、
    「この関数は何を受け取って何を返すのか」を機械的に参照できる

Pythonは、コードを読みやすく、メンテしやすくする工夫が随所に用意されています。

 4-2. 「データ」と「処理」をセットで考えるクセがつく

1つ目の例では、

  • データ:野菜の名前(文字列のリスト)
  • 処理:その文字列の「長さ」を基準に並び替える関数

2つ目の例では、

  • データ:文字列としての x, y
  • 処理:それらを連結する + メタ情報としての型ヒントを持つ関数

どちらも、

「どんなデータを扱うか」
「そのデータにどんな処理をするか」

をセットで考える練習になります。

5. 初学者向けまとめ:どの順番で理解するとラク?

最後に、学ぶ順番のおすすめを整理します。

  1. まずは素で動かしてみる
    • sort() の基本的な並び替え
    • print() で値がどう変わるか確認する
  2. key= と lambda をセットで覚える
    • 「key には基準となる値を返す関数を渡す」
    • lambda は小さな関数をその場で書くだけ
  3. 型ヒントの書き方に慣れる
    • x: str / -> str という記号の意味に馴染む
    • 実行時には強制されない「ヒント」であることを意識する
  4. __annotations__ で中身を覗いてみる
    • 型ヒントがどう保存されているかを見ることで、
      「Pythonはこうやって情報を持っているんだ」とイメージが掴みやすくなります。

6. おわりに

  • sort(key=lambda …) で「並び替えの基準」を自分で決められる
  • 関数に型ヒントをつけると「何を受け取って何を返すか」が読みやすくなる
  • __annotations__ を使うと、その型情報をコード側からも参照できる

この2つの例題だけでも、
Pythonの「関数の扱い方」「型のヒント」「コードの読みやすさを大事にする文化」を、かなりコンパクトに体験できます。

関連記事