Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python: รวม Dictionary สองตัว (Merge Dictionaries)

ใน Python มีหลายวิธีในการรวม Dictionary สองตัวหรือมากกว่า โดยแต่ละวิธีมีพฤติกรรมต่างกันเล็กน้อย ควรเลือกใช้ตามความเหมาะสม

วิธีที่ 1: ใช้ update() Method (In-place)

แก้ไข Dictionary ตัวแรกโดยตรง คืนค่า None

fruits = {"apple": 2, "orange": 3, "tangerine": 5}
dry_fruits = {"cashew": 3, "almond": 4, "pistachio": 6}

fruits.update(dry_fruits)
print(fruits)
# {'apple': 2, 'orange': 3, 'tangerine': 5, 'cashew': 3, 'almond': 4, 'pistachio': 6}

หมายเหตุ: ถ้ามี Key ซ้ำกัน ค่าจะถูก Overwrite โดยค่าจาก Dictionary ที่ส่งเข้าไปใน update()

วิธีที่ 2: ใช้ ** Unpacking Operator (Python 3.5+)

สร้าง Dictionary ใหม่ ไม่เปลี่ยนแปลงตัวเดิม

fruits = {"apple": 2, "orange": 3, "tangerine": 5}
dry_fruits = {"cashew": 3, "almond": 4, "pistachio": 6}

# Python 3.5+
merged = {**fruits, **dry_fruits}
print(merged)
# {'apple': 2, 'orange': 3, 'tangerine': 5, 'cashew': 3, 'almond': 4, 'pistachio': 6}

# ลำดับสำคัญ: ตัวหลัง Overwrite ตัวหน้า
merged2 = {**dry_fruits, **fruits}  # fruits overwrite dry_fruits

วิธีที่ 3: ใช้ Union Operator | (Python 3.9+)

Syntax ใหม่ที่อ่านง่ายที่สุด

# Python 3.9+
merged = fruits | dry_fruits
print(merged)

# In-place update (Python 3.9+)
fruits |= dry_fruits  # เทียบเท่า fruits.update(dry_fruits)

วิธีที่ 4: ใช้ dict() Constructor + **

merged = dict(fruits, **dry_fruits)
# หมายเหตุ: Key ต้องเป็น String เท่านั้น (Keyword Argument constraint)

วิธีที่ 5: ใช้ ChainMap (View แบบไม่ Copy)

from collections import ChainMap

# สร้าง View ที่รวมหลาย Dict (ไม่ Copy Data)
merged_view = ChainMap(fruits, dry_fruits)
print(merged_view["apple"])   # 2 (จาก fruits)
print(merged_view["cashew"])  # 3 (จาก dry_fruits)

# แปลงเป็น Dict ปกติถ้าต้องการ
merged_dict = dict(merged_view)

การจัดการ Key ซ้ำ (Duplicate Keys)

dict1 = {"a": 1, "b": 2, "common": 100}
dict2 = {"c": 3, "d": 4, "common": 200}

# วิธีต่างๆ จะให้ผลลัพธ์ต่างกันสำหรับ Key "common"
print({**dict1, **dict2})      # {'a':1, 'b':2, 'common':200, 'c':3, 'd':4}  (dict2 wins)
print({**dict2, **dict1})      # {'c':3, 'd':4, 'common':100, 'a':1, 'b':2}  (dict1 wins)
print(dict1 | dict2)           # dict2 wins (Python 3.9+)
dict1.update(dict2)            # dict1 becomes: common=200 (dict2 wins)

Deep Merge (Nested Dictionaries)

สำหรับ Nested Dict ต้องใช้ Recursive Function หรือ Library

def deep_merge(dict1, dict2):
    """Merge แบบ Recursive สำหรับ Nested Dict"""
    result = dict1.copy()
    for key, value in dict2.items():
        if key in result and isinstance(result[key], dict) and isinstance(value, dict):
            result[key] = deep_merge(result[key], value)
        else:
            result[key] = value
    return result

# ตัวอย่าง
config1 = {"db": {"host": "localhost", "port": 5432}, "debug": True}
config2 = {"db": {"port": 3306, "user": "admin"}, "logging": "info"}

merged_config = deep_merge(config1, config2)
print(merged_config)
# {'db': {'host': 'localhost', 'port': 3306, 'user': 'admin'}, 'debug': True, 'logging': 'info'}

สรุป: เลือกวิธีไหนดี?

สถานการณ์วิธีแนะนำ
Python 3.9+, ต้องการสร้าง Dict ใหม่dict1 | dict2
Python 3.5-3.8, ต้องการสร้าง Dict ใหม่{**dict1, **dict2}
ต้องการแก้ไข Dict เดิม (In-place)dict1.update(dict2) หรือ dict1 |= dict2
Memory Efficient, Read-only ViewChainMap(dict1, dict2)
Nested Dictionary (Deep Merge)Custom Function หรือ deepmerge library