ข้อมูลซ้อนกันใน Python: ลิสต์ ดิกชันนารี และโครงสร้างซับซ้อน
บทเรียนนี้แปลจากต้นฉบับภาษาอังกฤษRead in EnglishLeer en españolЧитать на русскомLer em portuguêsแจ้งข้อผิดพลาดในการแปล
ลองนึกถึงโรงเรียน โรงเรียนมีห้องเรียน แต่ละห้องมีนักเรียน นักเรียนแต่ละคนมีชื่อ อายุ และลิสต์ของคะแนน นั่นคือข้อมูลในข้อมูลในข้อมูลอีกที หรือที่เรียกว่าข้อมูลซ้อนกัน (nested data)
ข้อมูลซ้อนกันมีอยู่ทุกที่ในการเขียนโปรแกรมจริง แอปโซเชียลมีเดียเก็บผู้ใช้ที่มีโพสต์ และแต่ละโพสต์มีความคิดเห็น เกมเก็บด่านที่มีศัตรู และศัตรูแต่ละตัวมีค่าสถานะ ร้านค้าออนไลน์มีหมวดหมู่ที่มีสินค้าพร้อมรีวิว
ในบทเรียนนี้ คุณจะได้เรียนวิธีสร้าง เข้าถึง แก้ไข และวนลูปผ่านลิสต์และดิกชันนารีที่ซ้อนกัน ทักษะเหล่านี้จำเป็นมากสำหรับการทำงานกับข้อมูลในโลกจริง โดยเฉพาะ JSON จากเว็บ API
ลิสต์ซ้อนในลิสต์ทำงานอย่างไร
ลิสต์มีลิสต์อื่นเป็นสมาชิกได้ ทำให้เกิดโครงสร้างสองมิติ เหมือนกริดหรือตาราง ลองนึกถึงสเปรดชีตที่มีแถวและคอลัมน์
['X', 'O', 'X'] ['O', 'X', 'O'] ['X', ' ', 'O']
ถ้าต้องการเข้าถึงสมาชิกในลิสต์ซ้อนกัน ให้ใช้วงเล็บเหลี่ยมสองชุด วงเล็บแรกเลือกแถว วงเล็บที่สองเลือกคอลัมน์
X X
คุณแก้ไขสมาชิกได้ด้วยไวยากรณ์วงเล็บสองชุดแบบเดียวกัน นี่คือวิธีวางหมากในเกม XO (tic-tac-toe)
['X', ' ', 'X'] [' ', 'O', ' '] [' ', ' ', ' ']
ดิกชันนารีซ้อนกันทำงานอย่างไร
ค่าในดิกชันนารีเป็นดิกชันนารีอีกตัวได้ ทำให้เกิดโครงสร้างแบบต้นไม้ ที่คุณต้องไล่ลงไปทีละคีย์เพื่อไปถึงข้อมูลที่ต้องการ
Ms. Smith 25
วงเล็บเหลี่ยมแต่ละชุดพาคุณลึกลงไปหนึ่งชั้น school['Room 101'] ให้ดิกชันนารีด้านใน จากนั้น ['teacher'] ให้ค่าที่อยู่ในดิกชันนารีด้านในนั้น
คุณเพิ่มคีย์ใหม่หรืออัปเดตค่าได้ในทุกชั้น
Room 101: Ms. Smith teaches Algebra Room 103: Ms. Lee teaches Science
ลิสต์ของดิกชันนารี: รูปแบบที่พบบ่อยที่สุด
โครงสร้างซ้อนกันที่พบบ่อยที่สุดในการเขียนโปรแกรมจริงคือ ลิสต์ของดิกชันนารี ดิกชันนารีแต่ละตัวแทนข้อมูลหนึ่งรายการ (record) เช่น นักเรียนหนึ่งคน สินค้าหนึ่งชิ้น ผู้ใช้หนึ่งคน และลิสต์เก็บรายการทั้งหมดไว้ด้วยกัน
ถ้าคุณเคยเห็นข้อมูลจากเว็บ API หรือฐานข้อมูล มันแทบจะอยู่ในรูปลิสต์ของดิกชันนารีเสมอ
Alice 97 Alice is 15 and scored 92 Bob is 16 and scored 85 Charlie is 15 and scored 97
รูปแบบจะเป็น list[index][key] เสมอ ดัชนีเลือกว่าจะใช้ดิกชันนารีตัวไหน คีย์เลือกว่าจะใช้ค่าไหนในดิกชันนารีนั้น
วิธีเข้าถึงข้อมูลที่ซ้อนลึกอย่างปลอดภัย
ข้อมูลในโลกจริงอาจซ้อนกันหลายชั้น บริษัทมีแผนก แต่ละแผนกมีทีม แต่ละทีมมีสมาชิก การเข้าถึงข้อมูลที่ซ้อนลึกจึงต้องใช้วงเล็บหลายชุดต่อกัน
Alice Diana
อันตรายของการซ้อนลึกคือ ถ้าคีย์ไหนหายไป ก็จะเกิด KeyError ถ้าข้อมูลอาจไม่ครบ ให้ใช้เมธอด .get() ซึ่งคืนค่า None (หรือค่าเริ่มต้นที่กำหนด) แทนที่จะทำให้โปรแกรมหยุดทำงาน
Python developer No site default
วิธีวนลูปผ่านโครงสร้างข้อมูลซ้อนกัน
เมื่อมีข้อมูลซ้อนกัน คุณมักต้องใช้ลูปซ้อนกัน ลูปด้านนอกไล่ผ่านข้อมูลชั้นบนสุด และลูปด้านในไล่ผ่านข้อมูลที่อยู่ภายในแต่ละตัว บางครั้งก็มีฟังก์ชันทำงานชั้นในแทนให้: ในตัวอย่างแรกด้านล่าง sum() และ len() จัดการลิสต์ด้านในแต่ละตัว จึงใช้ลูปเดียวก็พอ
Math: average = 87.5 English: average = 85.0 Science: average = 87.2
grid[0][0] = 1 grid[0][1] = 2 grid[0][2] = 3 grid[1][0] = 4 grid[1][1] = 5 grid[1][2] = 6 grid[2][0] = 7 grid[2][1] = 8 grid[2][2] = 9
สำหรับลิสต์ของดิกชันนารี ลูปเดียวมักเพียงพอ เพราะดิกชันนารีแต่ละตัวคือข้อมูลหนึ่งรายการที่ครบในตัว
Laptop: $999 Phone: $699
วิธีสร้างโครงสร้างข้อมูลซ้อนกันตั้งแต่ต้น
ข้อมูลซ้อนกันไม่ได้มีคนเตรียมไว้ให้เสมอไป บางครั้งคุณต้องสร้างเอง รูปแบบที่ใช้บ่อยคือเริ่มจากโครงสร้างว่าง แล้วเพิ่มข้อมูลเข้าไปภายในลูป
a: ['apple', 'avocado'] b: ['banana', 'blueberry'] c: ['cherry', 'coconut']
อีกงานที่พบบ่อยคือการแปลงข้อมูลแบบแบนให้เป็นโครงสร้างซ้อนกัน เช่น เปลี่ยนลิสต์ชื่อ ลิสต์อายุ และลิสต์เกรดที่แยกกันอยู่ ให้เป็นลิสต์ของดิกชันนารี
{'name': 'Alice', 'age': 15, 'grade': 92}
{'name': 'Bob', 'age': 16, 'grade': 85}
{'name': 'Charlie', 'age': 15, 'grade': 97}แบบฝึกหัด
คุณมีกริดตัวเลขขนาด 3x3 ให้แสดงค่าตรงกลาง (แถว 1 คอลัมน์ 1) แล้วแสดงค่ามุมขวาล่าง (แถว 2 คอลัมน์ 2) แต่ละค่าอยู่คนละบรรทัด
อ่านโค้ดอย่างละเอียด โค้ดจะแสดงอะไร พิมพ์ผลลัพธ์ให้ตรงทุกตัวอักษร
วนลูปผ่านลิสต์ของนักเรียน แล้วหาคนที่ได้คะแนนสูงสุด แสดงชื่อและคะแนนในรูปแบบ: Best: Name (Grade)
จัดกลุ่มคำตามตัวอักษรแรกลงในดิกชันนารี จากนั้นแสดงแต่ละกลุ่มคนละบรรทัดในรูปแบบ: letter: [words]
แสดงตัวอักษรเรียงตามลำดับ
โค้ดนี้พยายามสร้างกริด 3x3 แล้วตั้งค่าเฉพาะช่องตรงกลางเป็น "X" แต่มีบางอย่างผิดพลาด ลองรันดู แก้บั๊กให้มีเพียงช่องตรงกลางที่เป็น "X" และช่องอื่นทั้งหมดยังเป็น "."
แสดงแต่ละแถวคนละบรรทัด
คุณมีดิกชันนารีที่แต่ละคีย์เป็นชื่อห้องเรียน และแต่ละค่าเป็นลิสต์ของดิกชันนารีนักเรียน คำนวณคะแนนเฉลี่ยของแต่ละห้อง แล้วแสดงในรูปแบบ: ClassName: average
ปัดค่าเฉลี่ยแต่ละค่าเป็นทศนิยม 1 ตำแหน่ง แสดงห้องเรียนเรียงตามตัวอักษร