1. *args — 可変長の位置引数
*args を使うと、関数が受け取る引数の数を固定しなくて済みます。
渡した引数は タプル として受け取れます。
「何個のデータを渡しても計算できる」汎用関数を作るときに便利です。
💡 重要なのは *(アスタリスク)であって、args という文字ではありません:
*args の args は単なる変数名です。*values、*scores、*data など、どんな名前でも同じように動きます。
def calc_mean(*values): # *values でも OK
def calc_mean(*args): # *args でも OK
def calc_mean(*numbers): # *numbers でも OK → すべて同じ動作
慣習として可変長の位置引数には *args、可変長のキーワード引数には **kwargs という名前がよく使われます。
下のコードでは *values・*args・*scores が混在していますが、すべて同じ仕組みです。
💡 *values と普通のリスト引数 values の違い:
リストを渡せば結果は同じになりますが、呼び出し側の書き方が変わります。
| 定義 | 呼び出し方 | 渡し方の制約 |
|---|---|---|
def f(*values): |
f(98, 97, 95) |
値をカンマ区切りで並べるだけでOK |
def f(values): |
f([98, 97, 95]) |
呼び出し側が必ずリストを用意する必要がある |
# *args を使うと、呼び出し元でリストを作らなくて済む
calc_mean(98, 97, 95) # ✅ そのまま渡せる
# リスト引数の場合は [] が必須
calc_mean_list([98, 97, 95]) # ✅ [] が必要
calc_mean_list(98, 97, 95) # ❌ TypeError
# 手元にリストがある場合は * で展開して渡せる
data = [98, 97, 95]
calc_mean(*data) # ✅ * で展開すると *args 関数にも渡せる
使い分けの目安:「バラバラの値を直接渡す」なら *args、
「すでにリストが手元にある」なら通常の引数でもOK。
PyTorchやライブラリのAPIでは *args スタイルが多く使われます。
2. **kwargs — 可変長のキーワード引数
**kwargs を使うと、名前=値 形式の引数を何個でも受け取れます。
受け取った引数は 辞書(dict) として扱えます。
*args が「いくつでも受け取れる位置引数(タプル)」なら、
**kwargs は「いくつでも受け取れるキーワード引数(辞書)」というイメージです。
どんなキーと値が渡されるか実行時まで決まらない柔軟なAPI・設定関数に使います。 機械学習フレームワークのモデル初期化やハイパーパラメータ管理でも このパターンが非常によく登場します。
💡 引数の順序ルール:
def f(通常引数, *args, **kwargs): の順番で書きます。
**kwargs は必ず最後です。
3. lambda 式 — 1行の無名関数
lambda 引数: 式 で1行の関数を作れます。
名前をつけるほどでもない小さな処理を sorted() や map() に渡すときに使います。
💡 なぜ sorted() に lambda を渡すのか:
sorted() の key パラメータは「各要素から比較に使う値を取り出す関数」を受け取ります。
辞書のリストはそのままでは何を基準に並べるか分からないため、key=... で「どの値を使うか」を関数で教えてあげる必要があります。
# ① 比較関数を def で書く場合(毎回名前をつけるのが手間)
def get_age(p):
return p["age"]
sorted(patients, key=get_age) # 関数を渡している
# ② lambda で同じことを1行で(名前不要・書き捨て)
sorted(patients, key=lambda p: p["age"])
# 意味: "患者辞書 p を受け取ったら p['age'] を返す" という
# 1行の関数をその場で作って sorted() に渡している
# ③ reverse=True を加えると降順
sorted(patients, key=lambda p: p["age"], reverse=True)
「1回しか使わない小さな処理」をその場で書き捨てるのが lambda の使いどころです。
処理が複雑な場合は素直に def で名前のある関数を書く方が読みやすくなります。
4. map() と filter()
map(関数, リスト) はリストの全要素に関数を適用します。
filter(関数, リスト) は条件が True の要素だけを抽出します。
どちらも list() で囲んでリストに変換して使います。
💡 内包表記 vs map/filter:
Python では [f(x) for x in lst] のような内包表記(次のレッスンで学習)がよく使われます。
map/filter と内包表記はどちらでも書けますが、
Pythonコミュニティでは内包表記の方が読みやすいとされています。
ただし map は大きなデータで遅延評価されるためメモリ効率が高い場面もあります。
5. 練習問題
可変長引数で検査値の統計を返す関数
*args を使って任意個の血糖値を受け取り、最大・最小・平均をタプルで返す関数 glucose_stats() を作ってください。
ヒントを見る(答え+解説)
def glucose_stats(*values):
return max(values), min(values), sum(values)/len(values)
high, low, avg = glucose_stats(110, 98, 125, 88, 142, 103)
print(f"最大: {high}, 最小: {low}, 平均: {avg:.1f}")
# → 最大: 142, 最小: 88, 平均: 104.3
*values は任意個の引数をタプルとしてまとめて受け取ります。return a, b, c で複数の値を返せるので、統計量をまとめて返す関数によく使われます。
lambda で患者リストを年齢降順にソートする
下の患者リストを lambda を使って年齢の降順にソートし、結果を表示してください。
ヒントを見る(答え+解説)
patients = [
{"name": "田中", "age": 58},
{"name": "鈴木", "age": 34},
{"name": "佐藤", "age": 71},
{"name": "高橋", "age": 45},
]
sorted_patients = sorted(patients, key=lambda p: p["age"], reverse=True)
for p in sorted_patients:
print(f"{p['name']}({p['age']}歳)")
# → 佐藤(71歳)/ 田中(58歳)/ 高橋(45歳)/ 鈴木(34歳)
sorted(key=lambda p: p["age"]) は「辞書の age キーの値で並び替え」を意味します。reverse=True で降順になり、患者を年齢順に並べる場面でよく使うパターンです。
filter で異常値を除外する
filter() を使って、下の心拍数リストから 40〜180 の正常範囲に入る値だけを抽出してください。
ヒントを見る(答え+解説)
heart_rates = [72, 185, 88, 35, 65, 210, 91, 78, 180, 15]
valid = list(filter(lambda hr: 40 <= hr <= 180, heart_rates))
print("正常範囲の心拍数:", valid)
# → 正常範囲の心拍数: [72, 88, 65, 91, 78, 180]
filter(条件関数, リスト) は条件を満たす要素だけを取り出します。lambda hr: 40 <= hr <= 180 のように Python の連鎖比較を使うと、範囲チェックを1行で書けます。
まとめ
このレッスンのポイント
*argsで任意個の位置引数をタプルとして受け取れる**kwargsで任意個のキーワード引数を辞書として受け取れる(PyTorchで多用)lambda x: 式で1行の無名関数。sorted(key=...)でよく使うmap(f, lst)で全要素変換、filter(f, lst)で条件抽出- Python では内包表記も同等の処理ができる(次レッスンで学習)
自由に試してみましょう:
完了するとトップページに進捗が表示されます
