🌐 Detecting your location…

بايثون: كيفية دمج قاموسين بكفاءة – مقارنة جميع الطرق (2026).

⏱️3 min read  ·  551 words

يعد دمج القواميس أحد أكثر عمليات بايثون شيوعًا. قدم Python 3.9+| (دمج) المشغل، مما يجعل النهج الأنظف أكثر نظافة. ولكن هناك ست طرق مختلفة لدمج القواميس، ولكل منها سلوك مختلف فيما يتعلق بالمفاتيح المكررة، والتغيير، والأداء. وهنا شرح كل طريقة.

مرجع سريع: نظرة سريعة على جميع الطرق

d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}

# 1. | operator (Python 3.9+) — RECOMMENDED for most cases
merged = d1 | d2 # {"a": 1, "b": 3, "c": 4}

# 2. |= operator — update d1 in-place (Python 3.9+)
d1 |= d2 # d1 is now {"a": 1, "b": 3, "c": 4}

# 3. ** unpacking — works in all Python 3.x
merged = {**d1, **d2} # {"a": 1, "b": 3, "c": 4}

# 4. .update() — in-place mutation
d1.update(d2) # d1 modified in-place, no return value

# 5. dict() constructor + unpacking
merged = dict(**d1, **d2) # {"a": 1, "b": 3, "c": 4}

# 6. ChainMap — lazy view of multiple dicts
from collections import ChainMap
merged = ChainMap(d1, d2) # ChainMap({'a':1,'b':2}, {'b':3,'c':4})

الطريقة الأولى: | المشغل (Python 3.9+ – مستحسن)

d1 = {"name": "Alice", "age": 30}
d2 = {"age": 31, "city": "Berlin"} # 'age' exists in both

result = d1 | d2
# {"name": "Alice", "age": 31, "city": "Berlin"}
# d2 values win on duplicate keys
# d1 is NOT modified — creates new dict

# Order matters: d2 | d1 would keep d1's age value
result_reversed = d2 | d1
# {"age": 30, "city": "Berlin", "name": "Alice"}
# d1 values win on duplicate keys

المشغل نظيف وقابل للقراءة ولا لبس فيه بشأن الإملاء الذي يفوز في الصراعات. تفضل هذا لمشاريع Python 3.9+.|الطريقة الثانية: |= للتحديث الموضعي (Python 3.9+)

استخدم

config = {"debug": False, "timeout": 30}
overrides = {"debug": True, "max_connections": 100}

config |= overrides
# config is now {"debug": True, "timeout": 30, "max_connections": 100}
# Modifies config in-place — no new dict created

عندما تريد تحديث إملاء موجود بقيم من أخرى. يعادل|= ولكن أكثر وضوحا حول دلالات الدمج.config.update(overrides)الطريقة الثالثة: {**d1, **d2} التفريغ (Python 3.5+)

يكون أكثر فائدة عند إنشاء أمر مضمن مع التجاوزات – وهو أمر شائع في أنماط التكوين. أقل قابلية للقراءة قليلاً من

defaults = {"color": "blue", "size": "medium"}
user_prefs = {"color": "red", "font": "arial"}

settings = {**defaults, **user_prefs}
# {"color": "red", "size": "medium", "font": "arial"}

# Advantage: can mix with literal keys
settings = {"version": "2.0", **defaults, **user_prefs, "modified": True}
# {"version":"2.0","color":"red","size":"medium","font":"arial","modified":True}

لعمليات الدمج البسيطة ولكن أكثر مرونة في التعبيرات.|الطريقة الرابعة: .update() للطفرة الموضعية

خطأ شائع:

# Returns None — common mistake: assigned to variable
d1 = {"a": 1}
result = d1.update({"b": 2})
print(result) # None — NOT the merged dict!
print(d1) # {"a": 1, "b": 2} — d1 was mutated

# Correct usage:
d1 = {"a": 1}
d1.update({"b": 2, "a": 99}) # duplicate key: new value wins
print(d1) # {"a": 99, "b": 2}

تعيين نتيجة إلى متغير – يقوم بإرجاع.update(). استخدمNone فقط عندما تريد عن قصد تغيير الإملاء الأول دون إنشاء واحد جديد..update()الطريقة الخامسة: ChainMap – عرض كسول بدون نسخ

أفضل حالة استخدام:

from collections import ChainMap

defaults = {"color": "blue", "debug": False, "size": 10}
production = {"debug": True}
local = {"size": 20, "extra": "value"}

# ChainMap looks up keys in order (local first, then production, then defaults)
config = ChainMap(local, production, defaults)
print(config["debug"]) # True (from production)
print(config["color"]) # "blue" (from defaults)
print(config["size"]) # 20 (from local)

# No copy made — changes to source dicts are reflected
defaults["color"] = "green"
print(config["color"]) # "green" — live view

طبقات التكوين (المحلية → البيئة → الافتراضية) حيث تريد عرضًا مرتبًا حسب الأولوية دون نسخ البيانات. عمليات البحث هي O(n) حيث n = عدد الإملاءات – تجنب عمليات البحث واسعة النطاق.مقارنة الأداء

تقع جميع طرق إنشاء الإملاء الجديد ضمن مسافة 15% من بعضها البعض. للعمليات في مكانها،

import timeit, collections

d1 = {i: i for i in range(1000)}
d2 = {i: i*2 for i in range(500, 1500)}

# Python 3.11+ benchmarks (microseconds for 10,000 iterations)
print(timeit.timeit(lambda: d1 | d2, number=10000)) # 5.1µs
print(timeit.timeit(lambda: {**d1, **d2}, number=10000)) # 5.4µs
print(timeit.timeit(lambda: {**d1, **d2}, number=10000)) # 5.4µs
print(timeit.timeit(lambda: dict(d1, **d2), number=10000)) # 5.8µs

و.update() أسرع نظرًا لعدم تخصيص أي إملاء جديد. يكون فرق الأداء ضئيلًا في معظم حالات الاستخدام — اختر بناءً على سهولة القراءة.|=الدمج العميق (القواميس المتداخلة)

الأسئلة المتداولة

# Standard merge doesn't deep-merge nested dicts
d1 = {"user": {"name": "Alice", "age": 30}}
d2 = {"user": {"email": "alice@example.com"}}

merged = d1 | d2
# {"user": {"email": "alice@example.com"}} — nested dict REPLACED not merged!

# Deep merge function
def deep_merge(base, override):
 result = base.copy()
 for key, value in override.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

merged = deep_merge(d1, d2)
# {"user": {"name": "Alice", "age": 30, "email": "alice@example.com"}} ✓

س: ما هي الطريقة التي يجب أن أستخدمها في Python 3.9+؟

ج: استخدم
لإنشاء إملاء مدمج جديد. استخدمd1 | d2 للحصول على التحديثات في المكان. كلاهما الأكثر بايثونية وقابلية للقراءة في بايثون الحديثة.d1 |= d2س: ماذا يحدث مع المفاتيح المكررة؟

ج: في جميع الطرق القياسية، تفوز قيمة الإملاء الموجود في أقصى اليمين (الأخير).
– قيمة d2 تفوز. d1 | d2 – قيمة d1 تفوز. الترتيب يتحكم في الأسبقية.{**d2, **d1}س: كيف يمكنني دمج إملاءين والاحتفاظ بالقيمتين للمفاتيح المكررة؟

ج: استخدم المنطق الافتراضي أو المنطق اليدوي:
. أو لدمج القوائم: كرر واستخدم setdefault.{k: [d1.get(k), d2.get(k)] for k in d1.keys() | d2.keys()}س: هل هناك سطر واحد للإملاءات المتعددة؟

سلاسل دمج المشغلين. أو :
A: merged = {} | d1 | d2 | d3س: هل الدمج يحافظ على ترتيب الإدراج؟from functools import reduce; merged = reduce(lambda a, b: a | b, [d1, d2, d3])

ج: نعم. تحافظ تعليمات Python 3.7+ على ترتيب الإدراج. في عمليات الدمج، تظهر المفاتيح بالترتيب: مفاتيح d1 الفريدة، ثم مفاتيح d2 (بما في ذلك التكرارات التي تم استبدالها بقيم d2).
الخلاصة

لمشاريع بايثون 3.9+:

استخدم للإملاءات المدمجة الجديدة وd1 | d2 للتحديثات الموضعيةd |= other. بالنسبة لبيثون الأقدم أو عند إنشاء تعبيرات معقدة:. استخدم{**d1, **d2} لطبقات التكوين دون النسخ. تجنبChainMap عندما تتوقع قيمة إرجاع – فإنها ترجعdict.update() وعادةً ما يكون تعديل البيانات في مكانها خيارًا خاطئًا للتعليمات البرمجية غير القابلة للتغيير.None وعادةً ما يكون تعديل البيانات في مكانها خيارًا خاطئًا للتعليمات البرمجية غير القابلة للتغيير.

MD Rafikul Islam

Written by

MD Rafikul Islam is a software developer and the editor of TechPulse. He writes about developer tooling, hardware, and the practical decisions that come up in day-to-day engineering work — which laptop to buy, which framework to commit to, why a build broke at 2am. He tests the tools he writes about and says plainly when something is not worth the money. Corrections and corrections requests are welcome at rony.yf25@gmail.com.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা