Python ทูเพิล (Tuple) และ Unpacking
ทูเพิล (Tuple) คือคอลเลกชันที่คล้ายกับลิสต์ (List) แต่มีความแตกต่างสำคัญคือ เมื่อสร้างแล้วจะไม่สามารถเพิ่ม ลบ หรือเปลี่ยนสมาชิกได้
สร้างทูเพิล
ใช้วงเล็บกลม () แทนวงเล็บเหลี่ยม
point = (10, 20)
rgb = (255, 128, 0)
person = ("สมชาย", 25, "กรุงเทพ")จริง ๆ วงเล็บไม่บังคับ แค่มีจุลภาคก็เป็นทูเพิลแล้ว
point = 10, 20
print(type(point)) # <class 'tuple'>ระวังทูเพิลตัวเดียว ต้องมีจุลภาคต่อท้าย ไม่งั้นมันเป็นแค่ค่าในวงเล็บ
a = (5) # นี่คือ int 5
b = (5,) # นี่คือ tuple ที่มีสมาชิกตัวเดียว
print(type(a), type(b)) # <class 'int'> <class 'tuple'>เข้าถึงสมาชิก
การเข้าถึงสมาชิกของทูเพิลทำได้คล้ายกับลิสต์ โดยใช้ index ทั้งค่าบวกและค่าลบ รวมถึงสามารถใช้ len() และวนลูปด้วย for ได้
person = ("สมชาย", 25, "กรุงเทพ")
print(person[0]) # สมชาย
print(person[-1]) # กรุงเทพ
print(len(person)) # 3
for item in person:
print(item)numbers = (10, 20, 30, 40, 50)
print(numbers[1:4]) # (20, 30, 40)แก้ไม่ได้ แปลว่าอะไร
point = (10, 20)
point[0] = 99 # TypeError: 'tuple' object does not support item assignmentคำถามคือ แล้วจะใช้ทำไมถ้าแก้ไม่ได้ คำตอบคือ ความแก้ไม่ได้เป็นข้อดีในหลายสถานการณ์
- ข้อมูลที่ไม่ควรเปลี่ยน เช่น พิกัด, ค่าสี RGB, วันเดือนปีเกิด ใช้ทูเพิลแล้วมั่นใจว่าไม่มีโค้ดส่วนไหนไปแก้โดยไม่ตั้งใจ
- เร็วกว่าและกินหน่วยความจำน้อยกว่า ลิสต์เล็กน้อย
- ทูเพิลสามารถใช้เป็นคีย์ของ dict ได้ หากสมาชิกภายในเป็นข้อมูลที่เหมาะสม เช่น ตัวเลขหรือข้อความ (ลิสต์ไม่สามารถใช้เป็นคีย์ได้)
locations = {
(13.75, 100.50): "กรุงเทพ",
(18.79, 98.98): "เชียงใหม่",
}
print(locations[(13.75, 100.50)]) # กรุงเทพUnpacking: แกะค่าออกมาทีเดียว
นี่คือของเด็ดที่ทำให้โค้ด Python อ่านสวย เอาสมาชิกในทูเพิล (หรือลิสต์) มาใส่ตัวแปรหลายตัวพร้อมกัน
person = ("สมชาย", 25, "กรุงเทพ")
name, age, city = person
print(name) # สมชาย
print(age) # 25
print(city) # กรุงเทพจำนวนตัวแปรทางซ้ายต้องตรงกับจำนวนสมาชิกที่ต้องการ unpack ไม่เช่นนั้นจะเกิด ValueError
สลับค่าตัวแปรแบบไม่ต้องมีตัวแปรพัก
ภาษาอื่นต้องสร้างตัวแปร temp แต่ Python ทำได้บรรทัดเดียว
a = 1
b = 2
a, b = b, a
print(a, b) # 2 1รับหลายค่าจากฟังก์ชัน
ใน Python เราสามารถเขียนฟังก์ชันให้คืนค่าหลายค่าได้ โดยค่าที่คั่นด้วยจุลภาคจะถูกรวมเป็นทูเพิล ซึ่งสามารถใช้ unpacking แยกออกเป็นหลายตัวแปรได้
def min_max(numbers):
return min(numbers), max(numbers)
low, high = min_max([4, 8, 1, 9, 3])
print(low, high) # 1 9เก็บส่วนที่เหลือด้วย *
ใส่ * หน้าตัวแปรตัวไหน มันจะกวาดสมาชิกที่เหลือมาเป็นลิสต์
scores = (90, 85, 78, 92, 88)
first, *rest = scores
print(first) # 90
print(rest) # [85, 78, 92, 88]
first, *middle, last = scores
print(first, last) # 90 88
print(middle) # [85, 78, 92]Unpacking ในลูป
เวลาวนลิสต์ของทูเพิล แกะออกมาใช้ในหัว for ได้เลย อ่านง่ายกว่าการใช้ index
students = [
("สมชาย", 85),
("สมหญิง", 92),
("สมศรี", 78),
]
for name, score in students:
print(f"{name}: {score}")จับคู่กับ enumerate() ที่เราใช้มาตลอด จริง ๆ มันก็คืนทูเพิล (index, value) มาให้เรา unpack นั่นเอง
แปลงไปมาระหว่าง list กับ tuple
t = (1, 2, 3)
lst = list(t) # [1, 2, 3]
lst.append(4)
t = tuple(lst) # (1, 2, 3, 4)หากต้องการเปลี่ยนข้อมูลในทูเพิล สามารถสร้างข้อมูลใหม่โดยแปลงทูเพิลเป็นลิสต์ แก้ไขข้อมูล แล้วแปลงกลับเป็นทูเพิลอีกครั้ง
สรุป
- ทูเพิลเหมือนลิสต์แต่แก้ไขไม่ได้ สร้างด้วย
()หรือแค่ใส่จุลภาค - ใช้กับข้อมูลที่ไม่ควรเปลี่ยน และใช้เป็นคีย์ของ dict ได้
- Unpacking (
a, b, c = tuple) ทำให้แกะค่า สลับตัวแปร และรับค่าหลายตัวจากฟังก์ชันได้สวยงาม *restกวาดสมาชิกที่เหลือมาเป็นลิสต์
บทถัดไปเป็นเซ็ต (Set) คอลเลกชันที่ไม่เก็บค่าซ้ำ และทำงานแบบเซ็ตในคณิตศาสตร์ได้