Notes & software courses · Free to learn
Aph's Blog
On this page

List / Array — โครงสร้างที่ใช้บ่อยที่สุด

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

เก็บข้อมูลหลายค่าในตัวแปรเดียว เข้าถึงด้วย index, slicing, เมธอดครบ และลิสต์ 2 มิติ

ในบทที่ 2 ตัวแปรหนึ่งตัวเก็บได้ค่าเดียว แต่ชีวิตจริงข้อมูลมาเป็นกลุ่ม เช่นคะแนนนักเรียน 40 คน เราคงไม่สร้างตัวแปร 40 ตัว List (ในหลายภาษาเรียก Array) คือคำตอบ — เก็บข้อมูลหลายค่าเรียงต่อกันในตัวแปรเดียว นี่คือโครงสร้างข้อมูลที่ใช้บ่อยที่สุดและเป็นพื้นฐานของแทบทุกข้อสอบ

สร้างลิสต์และเข้าถึงด้วย index

แต่ละช่องในลิสต์มีหมายเลขกำกับเรียกว่า index โดยเริ่มนับจาก 0 เสมอ (ไม่ใช่ 1!) นี่คือจุดที่มือใหม่พลาดบ่อยที่สุด

python
fruits = ["แอปเปิล", "กล้วย", "ส้ม", "มะม่วง"]
#  index:      0          1        2        3

print(fruits[0])    # แอปเปิล  (ตัวแรก index 0)
print(fruits[2])    # ส้ม
print(fruits[-1])   # มะม่วง   (index ติดลบ = นับจากท้าย)
print(fruits[-2])   # ส้ม      (ตัวที่ 2 จากท้าย)
print(len(fruits))  # 4        (จำนวนสมาชิก)

fruits[1] = "องุ่น"  # แก้ค่าในตำแหน่งได้
print(fruits)       # ['แอปเปิล', 'องุ่น', 'ส้ม', 'มะม่วง']
ทำไม index เริ่มที่ 0

เพราะ index แทน "ระยะห่างจากจุดเริ่มต้น" สมาชิกตัวแรกห่างจากจุดเริ่ม 0 ช่อง ตัวที่สองห่าง 1 ช่อง เข้าใจแบบนี้จะจำง่าย และ index ตัวสุดท้ายจะเป็น len - 1 เสมอ (ลิสต์ 4 ตัว index สุดท้ายคือ 3)

IndexError ที่เจอบ่อย

เข้าถึง index ที่เกินขนาดลิสต์จะ error เช่นลิสต์มี 4 ตัว (index 0-3) แต่เรียก fruits[4] จะได้ IndexError: list index out of range ระวังตอนวน loop อย่าให้เกิน len - 1

การหั่นลิสต์ (Slicing)

Slicing ดึงสมาชิกหลายตัวออกมาเป็นช่วงย่อย เขียนแบบ list[เริ่ม:จบ] โดย index ตัว "จบ" จะไม่ถูกรวม (เอาถึงก่อนหน้านั้น) เป็นเทคนิคที่ใช้บ่อยมาก

python
nums = [10, 20, 30, 40, 50]
print(nums[1:4])   # [20, 30, 40]  (index 1 ถึงก่อน 4)
print(nums[:3])    # [10, 20, 30]  (ตั้งแต่ต้นถึงก่อน 3)
print(nums[2:])    # [30, 40, 50]  (จาก index 2 ถึงท้าย)
print(nums[:])     # [10,20,30,40,50]  (สำเนาทั้งลิสต์)
print(nums[::2])   # [10, 30, 50]  (ก้าวทีละ 2)
print(nums[::-1])  # [50, 40, 30, 20, 10]  (กลับลำดับ!)
[::-1] กลับลำดับ

nums[::-1] เป็นวิธีกลับลำดับลิสต์ (หรือข้อความ) ที่สั้นที่สุด เจอบ่อยในโจทย์ เช่นเช็ค palindrome หรือกลับคำ จำสำนวนนี้ไว้ได้เลย

เพิ่ม ลบ และแก้ไขสมาชิก

python
nums = [3, 1, 2]

nums.append(4)      # เพิ่มท้าย      -> [3, 1, 2, 4]
nums.insert(0, 9)   # แทรกที่ index 0 -> [9, 3, 1, 2, 4]
nums.extend([5, 6]) # ต่อหลายตัว     -> [9, 3, 1, 2, 4, 5, 6]

nums.remove(9)      # ลบค่า 9 ตัวแรกที่เจอ -> [3, 1, 2, 4, 5, 6]
last = nums.pop()   # เอาตัวท้ายออก คืนค่า last=6
first = nums.pop(0) # เอา index 0 ออก คืนค่า first=3
del nums[0]         # ลบ index 0 (ไม่คืนค่า)
print(nums)
เมธอดทำอะไรเปลี่ยนลิสต์เดิมไหม
append(x)เพิ่ม x ต่อท้ายใช่
insert(i, x)แทรก x ที่ตำแหน่ง iใช่
extend(list)ต่อหลายตัวจากอีกลิสต์ใช่
remove(x)ลบค่า x ตัวแรกที่เจอใช่
pop(i)เอาตัวที่ i ออก + คืนค่า (ไม่ใส่ = ตัวท้าย)ใช่
clear()ล้างลิสต์ให้ว่างใช่

ค้นหา นับ และจัดเรียง

python
nums = [3, 1, 4, 1, 5, 1]

print(1 in nums)        # True   เช็คว่ามี 1 ไหม
print(nums.index(4))    # 2      ตำแหน่งของ 4
print(nums.count(1))    # 3      นับว่ามี 1 กี่ตัว
print(len(nums))        # 6
print(sum(nums))        # 15
print(min(nums), max(nums))  # 1 5

nums.sort()             # เรียงในตัวเอง -> [1,1,1,3,4,5]
nums.sort(reverse=True) # มากไปน้อย -> [5,4,3,1,1,1]
nums.reverse()          # กลับลำดับ -> [1,1,1,3,4,5]

# sorted() คืนลิสต์ใหม่ ไม่แก้ของเดิม
new_list = sorted([3, 1, 2])   # [1, 2, 3] ของเดิมไม่เปลี่ยน

วนลูปในลิสต์

python
scores = [80, 92, 75, 60]

for s in scores:                 # วนเอาค่า
    print(s)

for i, s in enumerate(scores):   # วนเอาทั้ง index และค่า
    print(f"คนที่ {i+1} ได้ {s} คะแนน")

total = sum(scores)
print(f"เฉลี่ย {total / len(scores)}")

ลิสต์ 2 มิติ (2D Array / ตาราง)

ลิสต์ซ้อนลิสต์ ใช้แทนตาราง กระดานเกม (หมากรุก, XO) หรือ matrix เข้าถึงด้วย index สองชั้น: grid[แถว][คอลัมน์]

python
grid = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]
print(grid[0][2])   # 3  (แถว 0 คอลัมน์ 2)
print(grid[2][0])   # 7  (แถว 2 คอลัมน์ 0)

# วนทุกช่อง
for row in grid:
    for cell in row:
        print(cell, end=" ")
    print()         # ขึ้นบรรทัดใหม่ทุกแถว

ระวัง! ลิสต์เป็น mutable และการ "คัดลอก"

ลิสต์แก้ไขได้ (mutable) และเมื่อกำหนด b = a ทั้งสองชื่อชี้ลิสต์เดียวกัน แก้ตัวหนึ่งกระทบอีกตัว นี่คือกับดักที่ทำให้มือใหม่งงมาก

python
a = [1, 2, 3]
b = a               # b ชี้ลิสต์เดียวกับ a (ไม่ใช่สำเนา!)
b.append(4)
print(a)            # [1, 2, 3, 4]  <- a เปลี่ยนด้วย!

# ถ้าต้องการสำเนาจริง ใช้ .copy() หรือ [:]
c = a.copy()        # หรือ a[:]
c.append(99)
print(a)            # ไม่เปลี่ยน (c เป็นลิสต์คนละก้อน)

เรียงข้อมูลซับซ้อนด้วย key= (ใช้บ่อยในงาน)

งานจริงมักเรียงลิสต์ของ dict/tuple ตามฟิลด์ใดฟิลด์หนึ่ง ใช้ sorted(key=...) บอกว่า "เรียงตามอะไร" — เทคนิคที่เจอแทบทุกวัน

python
students = [
    {"name": "Aph", "score": 80},
    {"name": "Bee", "score": 95},
    {"name": "Cha", "score": 70},
]

# เรียงตามคะแนนมากไปน้อย
ranked = sorted(students, key=lambda s: s["score"], reverse=True)
print(ranked[0]["name"])   # Bee

# เรียงคำตามความยาว
words = ["banana", "kiwi", "apple"]
print(sorted(words, key=len))   # ['kiwi', 'apple', 'banana']

# เรียงหลายเงื่อนไข: ตามคะแนน แล้วชื่อ (ใส่ tuple)
sorted(students, key=lambda s: (s["score"], s["name"]))

สรุปหัวข้อนี้

  • List เก็บหลายค่าเรียงกัน เข้าถึงด้วย index เริ่มที่ 0 (index สุดท้าย = len - 1)
  • Slicing list[start:end] ดึงช่วงย่อย (ไม่รวม end), [::-1] กลับลำดับ
  • เพิ่ม/ลบ: append, insert, extend, remove, pop, del
  • ค้นหา/จัดการ: in, index, count, sum, min, max, sort, sorted
  • ลิสต์ 2 มิติเข้าถึงด้วย grid[แถว][คอลัมน์]
  • ลิสต์เป็น mutable — b = a ชี้ก้อนเดียวกัน ต้องใช้ .copy() เพื่อสำเนาจริง
แบบฝึกหัด

1) สร้างลิสต์คะแนน 5 ตัว หาผลรวม ค่าเฉลี่ย มากสุด น้อยสุด 2) กลับลำดับลิสต์ด้วย [::-1] 3) รับตัวเลขจากผู้ใช้เก็บในลิสต์จนพิมพ์ 0 แล้วเรียงจากน้อยไปมาก 4) สร้างตาราง 3x3 แล้วหาผลรวมแต่ละแถว 5) ลองทดลอง b = a vs b = a.copy() ดูความต่าง