関数の定義と使い方
基本の関数定義
def greet(name):
print(f"こんにちは、{name}さん!")
greet("太郎") # こんにちは、太郎さん!
戻り値
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
# 複数の戻り値(タプルで返す)
def get_stats(numbers):
return min(numbers), max(numbers), sum(numbers) / len(numbers)
lo, hi, avg = get_stats([3, 1, 4, 1, 5, 9])
print(f"最小: {lo}, 最大: {hi}, 平均: {avg:.1f}")
引数の種類
デフォルト引数
def greet(name, greeting="こんにちは"):
print(f"{greeting}、{name}さん!")
greet("太郎") # こんにちは、太郎さん!
greet("花子", "おはよう") # おはよう、花子さん!
キーワード引数
def create_user(name, age, city="東京"):
return {"name": name, "age": age, "city": city}
# キーワードで指定すると順番は自由
user = create_user(age=25, name="太郎", city="大阪")
可変長引数
# *args: 位置引数を任意個数受け取る
def total(*args):
return sum(args)
print(total(1, 2, 3)) # 6
print(total(10, 20, 30, 40)) # 100
# **kwargs: キーワード引数を任意個数受け取る
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="太郎", age=25, city="東京")
ラムダ式(無名関数)
# 通常の関数
def double(x):
return x * 2
# ラムダ式
double = lambda x: x * 2
# ソートのキーとして使う
students = [("太郎", 85), ("花子", 92), ("次郎", 78)]
students.sort(key=lambda s: s[1], reverse=True)
print(students) # [('花子', 92), ('太郎', 85), ('次郎', 78)]
# filterと組み合わせ
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6, 8]
スコープ
x = "グローバル"
def outer():
x = "外側"
def inner():
x = "内側"
print(x) # 内側
inner()
print(x) # 外側
outer()
print(x) # グローバル
global と nonlocal
count = 0
def increment():
global count
count += 1
increment()
print(count) # 1
def outer():
value = 10
def inner():
nonlocal value
value += 5
inner()
print(value) # 15
outer()
注意:ミュータブルなデフォルト引数
# NG: リストをデフォルト引数にすると共有される
def add_item_bad(item, items=[]):
items.append(item)
return items
print(add_item_bad("a")) # ['a']
print(add_item_bad("b")) # ['a', 'b'] ← バグ!
# OK: Noneを使う
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
実践例:簡易電卓
def calculator(a, b, operation="+"):
operations = {
"+": lambda: a + b,
"-": lambda: a - b,
"*": lambda: a * b,
"/": lambda: a / b if b != 0 else "Error: 0除算",
}
func = operations.get(operation)
if func is None:
return "Error: 不明な演算子"
return func()
print(calculator(10, 3, "+")) # 13
print(calculator(10, 3, "*")) # 30
print(calculator(10, 0, "/")) # Error: 0除算
まとめ
def で関数を定義し return で値を返す
- デフォルト引数、キーワード引数、
*args、**kwargs で柔軟に
- ラムダ式は短い無名関数に使う
- ミュータブルなデフォルト引数は
None を使って回避
- スコープを理解して
global / nonlocal は慎重に使う