Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

วิธีหาค่าสูงสุดและต่ำสุด N รายการใน Python (Heapq vs Sorting)

บทความนี้สำหรับนักพัฒนาที่ต้องการหาค่าสูงสุด/ต่ำสุด N รายการใน Python จะเปรียบเทียบวิธีต่างๆ และสรุปวิธีที่ดีที่สุด

วิธีที่ 1: Slice Approach (เรียงลำดับแล้วตัด)

หาค่าต่ำสุด/สูงสุด 1 ค่า (N=1)

ใช้ min() และ max() เร็วที่สุด

import random
random_list = random.sample(range(1, 10), 9)
# [2, 4, 5, 1, 7, 9, 6, 8, 3]

min(random_list)  # 1
max(random_list)  # 9

หา 3 ค่าต่ำสุด/สูงสุด (N=3)

เหมาะเมื่อ N ใกล้เคียงขนาดข้อมูล

sorted(random_list)[:3]   # [1, 2, 3] - 3 ค่าต่ำสุด
sorted(random_list)[-3:]  # [7, 8, 9] - 3 ค่าสูงสุด

วิธีที่ 2: Heapq Module (เหมาะสำหรับ N เล็ก)

heapq.nsmallest() และ heapq.nlargest() ใช้ Heap Data Structure ประสิทธิภาพ O(n log k)

import heapq
import random

random_list = random.sample(range(1, 10), 9)

heapq.nsmallest(3, random_list)  # [1, 2, 3]
heapq.nlargest(3, random_list)   # [9, 8, 7]

รองรับ key parameter สำหรับข้อมูลซับซ้อน

grandslams = [
    {'name': 'Roger Federer', 'titles': 20},
    {'name': 'Rafael Nadal', 'titles': 19},
    {'name': 'Novak Djokovic', 'titles': 17},
    {'name': 'Andy Murray', 'titles': 3},
]

# 3 คนที่ชนะน้อยที่สุด
heapq.nsmallest(3, grandslams, key=lambda x: x['titles'])
# [{'name': 'Andy Murray', 'titles': 3}, {'name': 'Novak Djokovic', 'titles': 17}, {'name': 'Rafael Nadal', 'titles': 19}]

# 3 คนที่ชนะมากที่สุด
heapq.nlargest(3, grandslams, key=lambda x: x['titles'])
# [{'name': 'Roger Federer', 'titles': 20}, {'name': 'Rafael Nadal', 'titles': 19}, {'name': 'Novak Djokovic', 'titles': 17}]

หา N Largest/Smallest จาก DataFrame

วิธีที่ 1: sort_values() + head()

import pandas as pd
import io

data = """player,titles
Djokovic,17
Nadal,19
Federer,20
Murray,3"""

df = pd.read_csv(io.StringIO(data), index_col="player")

df.sort_values("titles").head(3)      # 3 คนน้อยที่สุด
df.sort_values("titles", ascending=False).head(3)  # 3 คนมากที่สุด

วิธีที่ 2: .nsmallest() และ .nlargest() (แนะนำ)

df.nsmallest(3, columns="titles")
df.nlargest(3, columns="titles")

เมธอดเหล่านี้ optimized แล้ว ไม่ต้องเรียงทั้ง DataFrame

สรุป: เลือกวิธีไหนดี?

ข้อสรุป: nlargest() และ nsmallest() เป็น adaptive implementation ที่ Python เลือกอัลกอริทึมที่ดีที่สุดให้อัตโนมัติ

สถานการณ์วิธีที่แนะนำ
N = 1 (ค่าเดียว)min() / max()
N เล็ก (N << n)heapq.nsmallest/nlargest หรือ df.nsmallest/nlargest
N ใกล้เคียงขนาดข้อมูลเรียงลำดับแล้ว slice (sorted()[:N])