Pythonリスト最大値・最小値取得完全ガイド – max()・min()から応用テクニックまで

 

Pythonでリストの最大値や最小値を取得することは、データ分析や統計処理において基本的かつ重要な操作です。基本的なmax()・min()関数の使い方から、複雑な条件による最大値・最小値の取得、パフォーマンスを考慮した実装まで、様々な手法があります。この記事では、リストの最大値・最小値取得に関するあらゆる方法を実例とともに詳しく解説します。

1. 基本的なmax()・min()関数

数値リストの最大値・最小値

numbers = [3, 7, 2, 9, 1, 5, 8]
maximum = max(numbers)
minimum = min(numbers)
print(f"最大値: {maximum}")  # 最大値: 9
print(f"最小値: {minimum}")  # 最小値: 1

文字列リストの最大値・最小値

words = ["apple", "banana", "cherry", "date"]
max_word = max(words)  # アルファベット順で最後
min_word = min(words)  # アルファベット順で最初
print(f"最大値: {max_word}")  # 最大値: date
print(f"最小値: {min_word}")  # 最小値: apple

2. 空リストのエラーハンドリング

def safe_max(lst):
    try:
        return max(lst)
    except ValueError:
        return None  # または適切なデフォルト値

def safe_min(lst):
    try:
        return min(lst)
    except ValueError:
        return None

empty_list = []
print(safe_max(empty_list))  # None
print(safe_min(empty_list))  # None

3. デフォルト値を指定した取得

# Python 3.4以降で使用可能
from statistics import median

numbers = []
max_val = max(numbers, default=0)
min_val = min(numbers, default=0)
print(f"最大値: {max_val}")  # 最大値: 0
print(f"最小値: {min_val}")  # 最小値: 0

# 条件付きで空リストの場合
scores = []
max_score = max(scores) if scores else "データなし"
print(max_score)  # データなし

4. key引数を使った条件付き最大値・最小値

文字列の長さによる最大値・最小値

words = ["cat", "elephant", "dog", "butterfly"]
longest = max(words, key=len)
shortest = min(words, key=len)
print(f"最長: {longest}")   # 最長: butterfly
print(f"最短: {shortest}")  # 最短: cat

絶対値による最大値・最小値

numbers = [-10, 3, -7, 15, -2]
max_abs = max(numbers, key=abs)
min_abs = min(numbers, key=abs)
print(f"絶対値最大: {max_abs}")  # 絶対値最大: 15
print(f"絶対値最小: {min_abs}")  # 絶対値最小: -2

5. 辞書のリストから最大値・最小値を取得

特定のキーによる最大値・最小値

students = [
    {"name": "Alice", "score": 85},
    {"name": "Bob", "score": 92},
    {"name": "Charlie", "score": 78}
]

best_student = max(students, key=lambda x: x["score"])
worst_student = min(students, key=lambda x: x["score"])

print(f"最高得点: {best_student}")   # {"name": "Bob", "score": 92}
print(f"最低得点: {worst_student}")  # {"name": "Charlie", "score": 78}

複数の条件による最大値・最小値

products = [
    {"name": "Laptop", "price": 80000, "rating": 4.5},
    {"name": "Phone", "price": 60000, "rating": 4.8},
    {"name": "Tablet", "price": 40000, "rating": 4.2}
]

# 価格とレーティングの積で評価
best_value = max(products, key=lambda x: x["price"] * x["rating"])
print(f"最高コスパ: {best_value['name']}")  # Phone

6. インデックスと一緒に取得

最大値・最小値のインデックスを取得

scores = [78, 92, 85, 67, 94, 73]

max_index = scores.index(max(scores))
min_index = scores.index(min(scores))

print(f"最高得点のインデックス: {max_index}")  # 4
print(f"最低得点のインデックス: {min_index}")  # 3

enumerate()を使った方法

data = [15, 8, 23, 4, 16, 42, 7]

max_item = max(enumerate(data), key=lambda x: x[1])
min_item = min(enumerate(data), key=lambda x: x[1])

print(f"最大値: インデックス{max_item[0]}, 値{max_item[1]}")  # インデックス5, 値42
print(f"最小値: インデックス{min_item[0]}, 値{min_item[1]}")  # インデックス3, 値4

7. 複数の最大値・最小値を取得

同じ最大値を持つ全ての要素

def find_all_max(lst):
    if not lst:
        return []
    max_val = max(lst)
    return [i for i, x in enumerate(lst) if x == max_val]

def find_all_min(lst):
    if not lst:
        return []
    min_val = min(lst)
    return [i for i, x in enumerate(lst) if x == min_val]

scores = [85, 92, 78, 92, 67, 85]
max_indices = find_all_max(scores)
min_indices = find_all_min(scores)

print(f"最高得点のインデックス: {max_indices}")  # [1, 3]
print(f"最低得点のインデックス: {min_indices}")  # [4]

8. 上位・下位N個の取得

sorted()を使った方法

numbers = [15, 8, 23, 4, 16, 42, 7, 31]

# 上位3個
top_3 = sorted(numbers, reverse=True)[:3]
print(f"上位3個: {top_3}")  # [42, 31, 23]

# 下位3個
bottom_3 = sorted(numbers)[:3]
print(f"下位3個: {bottom_3}")  # [4, 7, 8]

heapq.nlargest()・nsmallest()を使った方法

import heapq

numbers = [15, 8, 23, 4, 16, 42, 7, 31]

top_3 = heapq.nlargest(3, numbers)
bottom_3 = heapq.nsmallest(3, numbers)

print(f"上位3個: {top_3}")    # [42, 31, 23]
print(f"下位3個: {bottom_3}")  # [4, 7, 8]

9. 条件付き最大値・最小値

特定の条件を満たす要素の最大値・最小値

numbers = [1, 5, 3, 8, 2, 7, 4, 6, 9]

# 偶数の最大値・最小値
even_numbers = [x for x in numbers if x % 2 == 0]
if even_numbers:
    max_even = max(even_numbers)
    min_even = min(even_numbers)
    print(f"偶数の最大値: {max_even}")  # 偶数の最大値: 8
    print(f"偶数の最小値: {min_even}")  # 偶数の最小値: 2

filter()を使った方法

def conditional_max_min(lst, condition):
    filtered = list(filter(condition, lst))
    if not filtered:
        return None, None
    return max(filtered), min(filtered)

numbers = [1, 5, 3, 8, 2, 7, 4, 6, 9]
max_odd, min_odd = conditional_max_min(numbers, lambda x: x % 2 == 1)
print(f"奇数の最大値: {max_odd}, 最小値: {min_odd}")  # 9, 1

10. 2次元リストの最大値・最小値

全要素の最大値・最小値

matrix = [[1, 5, 3], [8, 2, 7], [4, 6, 9]]

# flatten してから取得
flat_list = [item for row in matrix for item in row]
global_max = max(flat_list)
global_min = min(flat_list)
print(f"全体の最大値: {global_max}")  # 9
print(f"全体の最小値: {global_min}")  # 1

# より簡潔な方法
global_max = max(max(row) for row in matrix)
global_min = min(min(row) for row in matrix)

行ごと・列ごとの最大値・最小値

matrix = [[1, 5, 3], [8, 2, 7], [4, 6, 9]]

# 各行の最大値・最小値
row_max = [max(row) for row in matrix]
row_min = [min(row) for row in matrix]
print(f"各行の最大値: {row_max}")  # [5, 8, 9]
print(f"各行の最小値: {row_min}")  # [1, 2, 4]

# 各列の最大値・最小値(転置してから計算)
col_max = [max(matrix[i][j] for i in range(len(matrix))) for j in range(len(matrix[0]))]
col_min = [min(matrix[i][j] for i in range(len(matrix))) for j in range(len(matrix[0]))]
print(f"各列の最大値: {col_max}")  # [8, 6, 9]
print(f"各列の最小値: {col_min}")  # [1, 2, 3]

11. カスタムオブジェクトの最大値・最小値

class Person:
    def __init__(self, name, age, salary):
        self.name = name
        self.age = age
        self.salary = salary
    
    def __repr__(self):
        return f"Person({self.name}, {self.age}, {self.salary})"

people = [
    Person("Alice", 25, 50000),
    Person("Bob", 30, 60000),
    Person("Charlie", 35, 55000)
]

# 年齢による最大値・最小値
oldest = max(people, key=lambda p: p.age)
youngest = min(people, key=lambda p: p.age)
print(f"最年長: {oldest}")  # Person(Charlie, 35, 55000)
print(f"最年少: {youngest}")  # Person(Alice, 25, 50000)

# 給与による最大値・最小値
highest_paid = max(people, key=lambda p: p.salary)
lowest_paid = min(people, key=lambda p: p.salary)
print(f"最高給与: {highest_paid}")  # Person(Bob, 30, 60000)

12. パフォーマンスの比較

大きなリストでの効率的な処理

import time

# 大きなリストでのパフォーマンステスト
large_list = list(range(1000000))

# max()関数
start = time.time()
max_val = max(large_list)
max_time = time.time() - start

# ループによる手動計算
start = time.time()
manual_max = large_list[0]
for num in large_list[1:]:
    if num > manual_max:
        manual_max = num
manual_time = time.time() - start

print(f"max()関数: {max_time:.4f}秒")
print(f"手動ループ: {manual_time:.4f}秒")
# 通常、max()関数の方が高速

13. NumPyとの比較

# Pythonリスト
py_list = [1, 5, 3, 8, 2, 7, 4, 6, 9]
py_max = max(py_list)
py_min = min(py_list)

# NumPy配列(参考)
# import numpy as np
# np_array = np.array([1, 5, 3, 8, 2, 7, 4, 6, 9])
# np_max = np_array.max()
# np_min = np_array.min()
# np_argmax = np_array.argmax()  # 最大値のインデックス
# np_argmin = np_array.argmin()  # 最小値のインデックス

14. 実用的な応用例

成績データの分析

class Student:
    def __init__(self, name, scores):
        self.name = name
        self.scores = scores
        self.average = sum(scores) / len(scores)

students = [
    Student("Alice", [85, 92, 78, 88]),
    Student("Bob", [76, 88, 91, 84]),
    Student("Charlie", [95, 87, 89, 93])
]

# 平均点が最高・最低の学生
best_avg_student = max(students, key=lambda s: s.average)
worst_avg_student = min(students, key=lambda s: s.average)

print(f"平均点最高: {best_avg_student.name} ({best_avg_student.average:.1f})")
print(f"平均点最低: {worst_avg_student.name} ({worst_avg_student.average:.1f})")

# 各科目の最高・最低点
num_subjects = len(students[0].scores)
for i in range(num_subjects):
    subject_scores = [student.scores[i] for student in students]
    max_score = max(subject_scores)
    min_score = min(subject_scores)
    print(f"科目{i+1}: 最高{max_score}点, 最低{min_score}点")

売上データの分析

monthly_sales = [
    {"month": "1月", "sales": 120000},
    {"month": "2月", "sales": 95000},
    {"month": "3月", "sales": 140000},
    {"month": "4月", "sales": 110000}
]

best_month = max(monthly_sales, key=lambda x: x["sales"])
worst_month = min(monthly_sales, key=lambda x: x["sales"])

print(f"最高売上月: {best_month['month']} ({best_month['sales']:,}円)")
print(f"最低売上月: {worst_month['month']} ({worst_month['sales']:,}円)")

# 売上の範囲
sales_values = [month["sales"] for month in monthly_sales]
sales_range = max(sales_values) - min(sales_values)
print(f"売上の幅: {sales_range:,}円")

15. エラーハンドリングのベストプラクティス

def robust_max_min(data, key_func=None):
    """堅牢な最大値・最小値取得関数"""
    if not data:
        return {"max": None, "min": None, "error": "空のデータ"}
    
    try:
        if key_func:
            max_val = max(data, key=key_func)
            min_val = min(data, key=key_func)
        else:
            max_val = max(data)
            min_val = min(data)
        
        return {"max": max_val, "min": min_val, "error": None}
    
    except (TypeError, ValueError) as e:
        return {"max": None, "min": None, "error": str(e)}

# 使用例
mixed_data = [1, "text", 3.14, None]
result = robust_max_min(mixed_data)
print(result)  # エラー情報付きで結果を返す

16. メモリ効率を考慮した実装

def streaming_max_min(iterable):
    """メモリ効率的な最大値・最小値取得"""
    iterator = iter(iterable)
    try:
        first = next(iterator)
        current_max = current_min = first
    except StopIteration:
        return None, None
    
    for item in iterator:
        if item > current_max:
            current_max = item
        elif item < current_min:
            current_min = item
    
    return current_max, current_min

# 大きなデータをジェネレータで処理
def large_numbers():
    for i in range(1000000):
        yield i * i - 500000

max_val, min_val = streaming_max_min(large_numbers())
print(f"最大値: {max_val}, 最小値: {min_val}")

まとめ

Pythonでリストの最大値・最小値を取得する方法は、基本的なmax()・min()関数から、複雑な条件による取得、パフォーマンスを考慮した実装まで多岐にわたります。

用途に応じて適切な手法を選択することが重要です。単純な数値リストであればmax()・min()関数が最も効率的ですが、辞書のリストやカスタムオブジェクトを扱う場合はkey引数を活用し、大きなデータセットではメモリ効率を考慮した実装を選択しましょう。

エラーハンドリングも忘れずに実装し、堅牢で保守性の高いコードを心がけることが大切です。

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座