ข้ามไปยังเนื้อหา

Comprehensions และ Generator Expressions

ใน TypeScript คุณแปลงและกรอง array ด้วยการต่อ method อย่าง .map(), .filter() และ .reduce() เข้าด้วยกัน ใช้ได้ดีอยู่ แต่ทุกขั้นตอนต้องสร้าง array กลางทางขึ้นมาใหม่

Python เลือกอีกทาง โดยฝังไว้ในภาษาเลย นั่นคือ comprehension ที่เป็น syntax กระชับสำหรับสร้าง list, dict หรือ set ใหม่จาก iterable ที่มีอยู่ พร้อมกรองค่าไปในตัวได้ภายในบรรทัดเดียว

รูปแบบพื้นฐานคือ [expression for item in iterable] และเพิ่ม if condition เพื่อกรองได้

TypeScript
// TypeScript: chained .map() and .filter()
const squares = [1, 2, 3, 4, 5].map(x => x ** 2);
console.log(squares); // [1, 4, 9, 16, 25]
const evens = Array.from({ length: 10 }, (_, i) => i).filter(x => x % 2 === 0);
console.log(evens); // [0, 2, 4, 6, 8]
// dict equivalent: Object.fromEntries + .map()
const words = ["hello", "world", "python"];
const wordLengths = Object.fromEntries(words.map(w => [w, w.length]));
console.log(wordLengths); // { hello: 5, world: 5, python: 6 }
Python
# Python: comprehension syntax — concise and readable
squares = [x ** 2 for x in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]
# dict comprehension
words = ["hello", "world", "python"]
word_lengths = {word: len(word) for word in words}
print(word_lengths) # {'hello': 5, 'world': 5, 'python': 6}

นอกจาก list แล้ว Python ยังรองรับ comprehension สำหรับ dict (ใช้ {} พร้อม key: value) และ set (ใช้ {} โดยไม่มี :) ด้วย

# set comprehension — ได้ unique values โดยอัตโนมัติ
unique_lengths = {len(word) for word in ["hi", "hello", "hey", "world"]}
print(sorted(unique_lengths)) # [2, 5]

ใน TypeScript การได้ผลลัพธ์แบบเดียวกันต้องผ่าน new Set(array.map(...)) แล้ว spread กลับ ซึ่งยุ่งยากกว่ามาก

Comprehension สร้าง collection ทั้งหมดในหน่วยความจำทันที Generator expression ใช้ () แทน [] และสร้างค่าทีละค่าตามที่ถูกขอ ทำให้เหมาะกับ sequence ขนาดใหญ่หรือ infinite sequence

# generator expression: ไม่สร้าง list จนกว่าจะวนซ้ำ
gen = (x ** 2 for x in range(5))
print(list(gen)) # [0, 1, 4, 9, 16]

เมื่อคุณส่ง generator expression เป็น argument ตัวเดียวให้ function คุณสามารถละวงเล็บชั้นนอกได้: sum(x ** 2 for x in range(100))

squares = [x ** 2 for x in range(1, 6)]
print(squares)
evens = [x for x in range(10) if x % 2 == 0]
print(evens)
word_lengths = {word: len(word) for word in ["hello", "world", "python"]}
print(word_lengths)
unique_lengths = {len(word) for word in ["hi", "hello", "hey", "world"]}
print(sorted(unique_lengths))
gen = (x ** 2 for x in range(5))
print(list(gen))
ผลลัพธ์ของ `[x * 2 for x in range(4)]` คืออะไร?
อะไรคือความแตกต่างหลักระหว่าง list comprehension และ generator expression?
syntax ใดที่ถูกต้องสำหรับ dict comprehension?