Pythonを学び始めると、
- リストの並び替え(sort())
- 無名関数(lambda)
- 型ヒント(x: str みたいな書き方)
といった「ちょっと難しそうに見える書き方」が急に出てきて、
モヤッとしがちです。
この記事では、次の2つのコード例を題材にしながら、
- sort(key=…) でリストを並び替える仕組み
lambdaの役割- 型ヒントと __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. 結果はどうなる?
「文字数の少ない順」に並ぶので、順番はこうなります。
"leek"(4文字)"tomato"(6文字)"cabbage"(7文字)"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行が実行されると、流れはこうなります。
func("Hello", "World")を呼び出し- 関数内の
print(func.__annotations__)が実行される {'x': <class 'str'>, 'y': <class 'str'>, 'return': <class 'str'>}が表示されるreturn x + "," + yによって"Hello,World"が返ってくる- 外側の
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. 初学者向けまとめ:どの順番で理解するとラク?
最後に、学ぶ順番のおすすめを整理します。
- まずは素で動かしてみる
- sort() の基本的な並び替え
- print() で値がどう変わるか確認する
- key= と lambda をセットで覚える
- 「key には基準となる値を返す関数を渡す」
- lambda は小さな関数をその場で書くだけ
- 型ヒントの書き方に慣れる
- x: str / -> str という記号の意味に馴染む
- 実行時には強制されない「ヒント」であることを意識する
- __annotations__ で中身を覗いてみる
- 型ヒントがどう保存されているかを見ることで、
「Pythonはこうやって情報を持っているんだ」とイメージが掴みやすくなります。
- 型ヒントがどう保存されているかを見ることで、
6. おわりに
- sort(key=lambda …) で「並び替えの基準」を自分で決められる
- 関数に型ヒントをつけると「何を受け取って何を返すか」が読みやすくなる
- __annotations__ を使うと、その型情報をコード側からも参照できる
この2つの例題だけでも、
Pythonの「関数の扱い方」「型のヒント」「コードの読みやすさを大事にする文化」を、かなりコンパクトに体験できます。




