Kodokon kodokon.com

โครงสร้างขั้นสูง: ทูเพิล เซต และ collections

เลือกโครงสร้างให้เหมาะกับแต่ละความต้องการ: ทูเพิลที่เปลี่ยนแปลงไม่ได้ เซตสำหรับการทดสอบสมาชิกแบบ O(1) และ Counter กับ defaultdict สำหรับแพทเทิร์นที่พบซ้ำ ๆ

9 นาที · 3 คำถาม

เปิดบทเรียนนี้ใน Kodokon

การเลือกโครงสร้างข้อมูลให้ถูกต้องช่วยจัดการทั้งความอ่านง่ายและประสิทธิภาพได้ในคราวเดียว ทูเพิล คือลำดับที่เปลี่ยนแปลงไม่ได้ เหมาะอย่างยิ่งสำหรับระเบียนขนาดคงที่ที่มีข้อมูลต่างชนิดกัน (พิกัด หรือคู่คีย์-ค่า) การเปลี่ยนแปลงไม่ได้หมายถึง แฮชได้ (hashable) (ถ้าสิ่งที่อยู่ข้างในแฮชได้ด้วย) ทูเพิลจึงใช้เป็นคีย์ของดิกชันนารีหรือสมาชิกของเซตได้ ในขณะที่ลิสต์ทำไม่ได้ การแตกค่า (unpacking) ทำให้โค้ดสื่อความหมาย - และฟังก์ชันที่ "คืนค่าหลายค่า" จริง ๆ แล้วคืนทูเพิลหนึ่งตัว

PYTHON
point = (48.85, 2.35)
lat, lon = point

def min_max(values):
    return min(values), max(values)

low, high = min_max([3, 1, 4, 1, 5])
print(low, high)

distances = {("paris", "lyon"): 465}
print(distances[("paris", "lyon")])
การแตกค่า การคืนค่าหลายค่า และทูเพิลในฐานะคีย์ของดิกชันนารี

เซต รับประกันความไม่ซ้ำ และให้การทดสอบสมาชิกด้วยเวลา O(1) โดยเฉลี่ย ในขณะที่ลิสต์เป็น O(n) ในลูปที่ตรวจ x in collection นับพันครั้ง ความต่างจะปรากฏให้เห็นทันที ตัวดำเนินการของเซต (& อินเตอร์เซกชัน, - ผลต่าง, | ยูเนียน) คือการยกระดับที่แท้จริงเมื่อเทียบกับลูปซ้อนลูป การเปรียบเทียบลิสต์ตัวระบุสองชุด - ใครหายไป ใครเป็นคนใหม่ - จบได้ในสองบรรทัด

PYTHON
active = {"ada", "linus", "guido"}
banned = {"linus", "mallory"}

print(active & banned)
print(active - banned)
print(active | banned)

emails = ["a@x.io", "b@x.io", "a@x.io"]
unique = set(emails)
print(len(unique))
การดำเนินการกับเซตและการกำจัดค่าซ้ำ

มอดูล collections ครอบคลุมสองความต้องการที่พบทุกวัน Counter นับจำนวนครั้งที่ปรากฏในอ็อบเจกต์ที่วนซ้ำได้ และมี most_common(n) ให้ใช้ - ไม่ต้องเขียนดิกชันนารีสำหรับนับด้วยมืออีกต่อไป ส่วน defaultdict(factory) จะสร้างค่าที่ขาดหายไปขึ้นมาให้ทันที defaultdict(list) คือเครื่องมือมาตรฐานสำหรับ การจัดกลุ่ม สมาชิกตามคีย์ โดยไม่ต้องตรวจสอบว่าคีย์นั้นมีอยู่หรือไม่ในทุกรอบของลูป

PYTHON
from collections import Counter, defaultdict

words = ["go", "py", "go", "rs", "go"]
counts = Counter(words)
print(counts.most_common(2))

groups = defaultdict(list)
pairs = [("fr", "Ada"), ("us", "Lin"), ("fr", "Zoe")]
for country, name in pairs:
    groups[country].append(name)
print(dict(groups))
Counter ไว้นับ defaultdict ไว้จัดกลุ่ม

ทดสอบความรู้

ตรวจสอบว่าคุณจำประเด็นสำคัญของบทเรียนนี้ได้ครบถ้วน

  1. ทำไมทูเพิลจึงใช้เป็นคีย์ของดิกชันนารีได้ ต่างจากลิสต์?
    • มันสร้างได้เร็วกว่า
    • มันเปลี่ยนแปลงไม่ได้ จึงแฮชได้
    • มันบรรจุได้แต่ตัวเลขเท่านั้น
    • ดิกชันนารีแปลงลิสต์ให้เป็นทูเพิลอยู่แล้ว
  2. คุณทดสอบ x in collection นับพันครั้งบนสมาชิก 100,000 ตัว ควรเลือกโครงสร้างใด?
    • ลิสต์ ที่ไล่อ่านทีละตัวตามลำดับ
    • เซต ที่ทดสอบสมาชิกด้วยเวลา O(1) โดยเฉลี่ย
    • ทูเพิล ที่กระชับกว่าลิสต์
  3. เมื่อ groups = defaultdict(list) การอ่านคีย์ที่ไม่มีอยู่จะทำอะไร?
    • มันโยน KeyError
    • มันคืนลิสต์ว่างและแทรกคีย์นั้นเข้าไป
    • มันคืน None โดยไม่แก้ไขดิกชันนารี