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

Python - การใช้ 2D Arrays/Lists อย่างถูกต้อง

Python มีหลายวิธีสร้าง 2D lists/arrays แต่ต้องรู้ความแตกต่าง เพราะอาจสร้างบั๊กที่ยากต่อการติดตาม

ตัวอย่างโค้ด

❌ วิธีผิด: ใช้ * ซ้อนกัน (Shallow Copy)


rows, cols = (5, 5)
arr = [[0] * cols] * rows

# เปลี่ยนแปลง arr[0][0] = 1
arr[0][0] = 1

for row in arr:
    print(row)

✅ วิธีถูกต้อง: ใช้ List Comprehension


rows, cols = (5, 5)
arr = [[0 for i in range(cols)] for j in range(rows)]

arr[0][0] = 1

for row in arr:
    print(row)

ผลลัพธ์


# วิธีผิด - ทุกแถวเปลี่ยนไปพร้อมกัน!
[1, 0, 0, 0, 0]
[1, 0, 0, 0, 0]
[1, 0, 0, 0, 0]
[1, 0, 0, 0, 0]
[1, 0, 0, 0, 0]

# วิธีถูกต้อง - เฉพาะแถวแรกเปลี่ยน
[1, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]

ทำไมวิธีแรกจึงผิด?


# [[0] * cols] * rows
# ขั้นตอน:
# 1. [0] * cols → สร้างลิสต์ [0, 0, 0, 0, 0] (1 ออบเจ็กต์)
# 2. [...] * rows → คัดลอก reference ของลิสต์เดียวกัน 5 ครั้ง
# ผลลัพธ์: 5 reference ชี้ไปที่ลิสต์เดียวกัน!

# ตรวจสอบด้วย id()
arr = [[0] * 3] * 3
print(id(arr[0]), id(arr[1]), id(arr[2]))  # เลข id เหมือนกันทั้ง 3!

วิธีสร้าง 2D List ที่ถูกต้อง

1. List Comprehension (แนะนำ)


rows, cols = 5, 5
arr = [[0 for _ in range(cols)] for _ in range(rows)]
# หรือ
arr = [[0] * cols for _ in range(rows)]  # [0]*cols สร้างลิสต์ใหม่ทุกครั้ง

2. ใช้ NumPy (แนะนำสำหรับงานคำนวณ)


import numpy as np

arr = np.zeros((5, 5), dtype=int)
arr[0, 0] = 1
print(arr)

3. ใช้ copy.deepcopy() ถ้าต้องคัดลอก 2D list ที่มีอยู่


import copy

original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(original)

สรุป

  • ❌ [[0]*cols]*rows - สร้าง reference ซ้ำ ผิด!
  • ✅ [[0]*cols for _ in range(rows)] - สร้างลิสต์ใหม่ทุกแถว ถูกต้อง!
  • ✅ np.zeros((rows, cols)) - ใช้ NumPy สำหรับงานตัวเลข
  • ✅ copy.deepcopy() - คัดลอกลึกสำหรับ nested structures