การใช้ List Comprehensions ร่วมกับ map() ใน Python

แชร์ความรู้ภาษา Python ไพทอน การเขียนโปรแกรมภาษาไพทอน

Moderator: mindphp, ผู้ดูแลกระดาน

Sakana
PHP Super Member
PHP Super Member
โพสต์: 307
ลงทะเบียนเมื่อ: 16/06/2025 9:38 am

การใช้ List Comprehensions ร่วมกับ map() ใน Python

โพสต์ที่ยังไม่ได้อ่าน โดย Sakana »

ในโลกของ Python, List Comprehensions และฟังก์ชัน map() ต่างก็เป็นเครื่องมือที่มีประสิทธิภาพสำหรับการแปลงหรือประมวลผลข้อมูลใน Iterables (เช่น ลิสต์, ทูเพิล) ให้กลายเป็นลิสต์ใหม่ ด้วยความสามารถที่คล้ายคลึงกัน บางครั้งนักพัฒนาอาจสงสัยว่าควรเลือกใช้อะไรดี หรือในบางกรณี ทั้งสองอาจปรากฏอยู่ในโค้ดเดียวกันได้ บทความนี้จะอธิบายถึงบทบาทของแต่ละส่วน และวิธีที่คุณอาจพบเจอการใช้งานทั้งสองร่วมกัน

ทบทวนพื้นฐาน: List Comprehensions และ map()
ก่อนที่เราจะพูดถึงการใช้งานร่วมกัน มาทบทวนบทบาทของแต่ละฟังก์ชันโดยย่อ:
- List Comprehensions:
  • เป็นรูปแบบการสร้างลิสต์ใหม่ที่สั้น กระชับ และอ่านง่าย โดยสามารถรวมการแปลงข้อมูล (mapping) และการกรองข้อมูล (filtering) เข้าไว้ในบรรทัดเดียว มักเป็นที่นิยมสำหรับงานที่ตรงไปตรงมาและต้องการสร้างลิสต์ใหม่จาก Iterable เดิม
    รูปแบบ:

    โค้ด: เลือกทั้งหมด

    [expression for item in iterable if condition]
    ตัวอย่าง:

    โค้ด: เลือกทั้งหมด

    squared_numbers = [x**2 for x in [1, 2, 3]]
- map():
  • เป็นฟังก์ชัน Built-in ที่ใช้สำหรับ "ประยุกต์ใช้" ฟังก์ชันที่ระบุลงบนสมาชิกแต่ละตัวของ Iterable และส่งคืน map object (ซึ่งเป็น Iterator) มักใช้เมื่อมีฟังก์ชันที่คุณต้องการนำไปใช้กับสมาชิกจำนวนมาก หรือเมื่อต้องการประมวลผลแบบ Lazy Evaluation (ประมวลผลทีละตัวเมื่อถูกเรียกใช้)
    รูปแบบ:

    โค้ด: เลือกทั้งหมด

    map(function, iterable, ...)
    ตัวอย่าง:

    โค้ด: เลือกทั้งหมด

    squared_numbers = list(map(lambda x: x**2, [1, 2, 3]))
เมื่อไหร่ที่คุณอาจเห็น List Comprehensions และ map() "ร่วมกัน"?
โดยทั่วไปแล้ว List Comprehensions และ map() มักถูกใช้เป็น ทางเลือก ซึ่งกันและกันสำหรับการแปลงข้อมูล อย่างไรก็ตาม มีบางสถานการณ์ที่คุณอาจพบว่ามีการใช้งานร่วมกัน (แต่ส่วนใหญ่อาจไม่ใช่การ "ซ้อนกัน" โดยตรง) ดังนี้:

สถานการณ์ที่ 1: ใช้ List Comprehensions เพื่อแปลง map Object เป็น List (พบบ่อยที่สุด)
เนื่องจาก map() คืนค่าเป็น map object (ซึ่งเป็น Iterator) เพื่อประหยัด Memory และประมวลผลแบบ Lazy Evaluation คุณมักจะต้องแปลง map object ให้เป็นลิสต์จริงๆ เพื่อนำไปใช้งานต่อ หรือเพื่อดูผลลัพธ์ทั้งหมด และวิธีหนึ่งที่ทำได้คือการใช้ List Comprehensions (แม้ว่า list() constructor จะเป็นวิธีที่ตรงกว่า)

ตัวอย่าง: แปลงสตริงในลิสต์ให้เป็นตัวพิมพ์ใหญ่ด้วย map() จากนั้นประมวลผลเพิ่มเติมด้วย List Comprehensions (ในตัวอย่างนี้อาจดูไม่จำเป็น แต่แสดงให้เห็นการไหลของข้อมูล)

โค้ด: เลือกทั้งหมด

words = ["hello", "world", "python"]

# 1. ใช้ map() เพื่อแปลงเป็นตัวพิมพ์ใหญ่ (ผลลัพธ์คือ map object)
uppercase_map_object = map(str.upper, words)
print(f"Type of map object: {type(uppercase_map_object)}") # Output: <class 'map'>

# 2. ใช้ List Comprehension เพื่อดึงค่าจาก map object และสร้าง list ใหม่
#    และในขณะเดียวกันก็เพิ่มข้อความ "!" ท้ายคำ
final_words = [word + "!" for word in uppercase_map_object]

print(f"Final words: {final_words}") # Output: Final words: ['HELLO!', 'WORLD!', 'PYTHON!']
ผลลัพธ์
Python Knowledge-1.png
Python Knowledge-1.png (2.68 KiB) Viewed 79 times
ในตัวอย่างนี้ List Comprehensions ทำหน้าที่เหมือนตัวรวบรวมและแปลงข้อมูลจาก map object อีกทอดหนึ่ง

สถานการณ์ที่ 2: ใช้ map() เพื่อเตรียมข้อมูลสำหรับ List Comprehensions (ไม่ค่อยพบบ่อยนัก)
เป็นไปได้ที่จะใช้ map() เพื่อประมวลผลเบื้องต้นกับข้อมูลจำนวนมากก่อน แล้วค่อยส่งผลลัพธ์ที่เป็น map object (ซึ่งเป็น Iterator) เข้าไปใน List Comprehensions เพื่อประมวลผลต่อพร้อมกับเงื่อนไขการกรอง

ตัวอย่าง: ประมวลผลตัวเลขโดยใช้ map() เพื่อยกกำลังสองก่อน แล้วค่อยใช้ List Comprehensions กรองเฉพาะตัวเลขคู่

โค้ด: เลือกทั้งหมด

numbers = [1, 2, 3, 4, 5, 6]

# 1. ใช้ map() เพื่อยกกำลังสอง (ผลลัพธ์คือ map object)
squared_numbers_map = map(lambda x: x**2, numbers)

# 2. ใช้ List Comprehensions เพื่อกรองเฉพาะตัวเลขคู่จากผลลัพธ์ของ map
even_squared_numbers = [num for num in squared_numbers_map if num % 2 == 0]

print(f"Even squared numbers: {even_squared_numbers}")
# Output: Even squared numbers: [4, 16, 36]
ผลลัพธ์
Python Knowledge-1.png
Python Knowledge-1.png (1.4 KiB) Viewed 79 times
ในกรณีนี้ map() ช่วยให้เรามี Iterator ของ squared_numbers ซึ่งจากนั้น List Comprehensions จะวนซ้ำและกรองข้อมูลให้เหลือเฉพาะค่าที่ต้องการ


สรุป: เมื่อไหร่ควรใช้อะไร?
- เลือก List Comprehensions เป็นอันดับแรก: สำหรับงานส่วนใหญ่ที่เกี่ยวข้องกับการแปลงและ/หรือกรองข้อมูลจาก Iterable เพื่อสร้างลิสต์ใหม่ โดยเฉพาะอย่างยิ่งเมื่อโค้ดมีความซับซ้อนไม่มาก และต้องการผลลัพธ์เป็นลิสต์ทันที List Comprehensions มักจะอ่านง่ายกว่า
- เลือก map():
  • เมื่อคุณมีฟังก์ชันที่ซับซ้อนที่ประกาศไว้อยู่แล้ว และต้องการนำไปใช้กับ Iterable โดยไม่ต้องสร้าง lambda ที่ยาวหรือซับซ้อน
    เมื่อคุณต้องการประหยัด Memory สำหรับชุดข้อมูลขนาดใหญ่มากๆ โดยต้องการผลลัพธ์เป็น Iterator (Lazy Evaluation) และจะวนซ้ำแค่บางส่วนหรือประมวลผลทีละตัว
- การใช้งานร่วมกัน:
  • สถานการณ์ที่พบบ่อยที่สุดคือการใช้ List Comprehensions หรือ list() เพื่อ ดึงค่าจาก map object และแปลงให้เป็นลิสต์ที่ใช้งานได้
    การใช้ map() เพื่อทำ "Pre-processing" บางอย่างกับชุดข้อมูลขนาดใหญ่ ก่อนที่จะส่งผ่านเข้าสู่ List Comprehensions เพื่อการกรองหรือประมวลผลขั้นสุดท้าย ก็เป็นไปได้ แต่ต้องพิจารณาความจำเป็นและความชัดเจนของโค้ด
ลิ้งค์อ้างอิง
- https://www.mindphp.com/คู่มือ/73-คืออะ ... ออะไร.html
- viewtopic.php?t=45663
- https://www.mindphp.com/บทเรียนออนไลน์/ ... -type.html
- https://www.mindphp.com/บทเรียนออนไลน์/ ... -type.html
- viewtopic.php?t=107367
- viewtopic.php?t=116403
  • Similar Topics
    ตอบกลับ
    แสดง
    โพสต์ล่าสุด

ผู้ใช้งานขณะนี้

สมาชิกกำลังดูบอร์ดนี้: ไม่มีสมาชิกใหม่ และบุคลทั่วไป 1