• 0

الوصول إلى عناصر القاموس المتداخلة عبر قائمة من المفاتيح في بايثون

لدي قاموس كالتالي:


dataDict = {
    "a":{
        "x": 1,
        "y": 2,
        "z": 3
        },
    "b":{
        "x": 1,
        "y": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "z": 3
        }
}    

كيف يمكنني الوصول إلى القيمة 3 من القاموس من خلال قائمة المفاتيح السابقة؟ أي كيف أقوم باستخدام القائمة السابقة للحصول على القيمة الموجودة في القاموس بنفس الطريقة التالية:

dataDict["b"]["y"]["z"]

كيف يمكنني الوصول إلى القيمة 3 من القاموس من خلال قائمة المفاتيح السابقة؟ هل توجد مكتبة / دولة قياسية تقوم بهذا الأمر بشكل سريع؟

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 1

إذا كنت تقصد أنه إنطلاقاً من قائمة تحتوي على مفاتيح:

["b", "y", "z"]

تُريد الوصول إلى قيمة في القاموس المُعطى.

يُمكنك إنشاء دالة للمرور على القائمة و جلب القيمة في كل مرة بالشكل التالي:

dataDict = {
    "a":{
        "x": 1,
        "y": 2,
        "z": 3
    },
    "b":{
        "x": 1,
        "y": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "z": 3
    }
}  

def nested_get(dic, keys):    
    for key in keys:
        dic = dic[key]
    return dic

print(nested_get(dataDict, ["b", "y", "z"])) # 3

كما بالإمكان إستخدام functools.reduce بالشكل التالي:

from functools import reduce
import operator

def nested_get(dataDict, mapList):
    return reduce(operator.getitem, mapList, dataDict)

dataDict = {
    "a":{
        "x": 1,
        "y": 2,
        "z": 3
    },
    "b":{
        "x": 1,
        "y": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "z": 3
    }
}  

print(nested_get(dataDict, ["b", "y", "z"])) # 3

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 1

أنا استخدم مكتبة dpath وهي سريعة بما يكفي ومصممة خصيصاً للتعامل مع هكذا مهام في القواميس كالتالي:

# أولاً قم بتحميلها
# pip install dpath
dataDict = {
    "a":{
        "x": 1,
        "y": 2,
        "z": 3
        },
    "b":{
        "x": 1,
        "y": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "z": 3
        }
} 
# استيراد المكتبة
import dpath.util
# البحث عن القيمة المطلوبة
value1=dpath.util.get(dataDict, '/a/z') # نمرر القاموس والمسار المطلوب
print(value1)
value1=dpath.util.get(dataDict, '/b/y/z')
print(value2)

هناك طرق أخرى، مثلاً يمكنك استخدام الدالة reduce من الموديول functools كالتالي:

from functools import reduce
import operator
def getFromDict(dataDict, mapList):
    return reduce(operator.getitem, mapList, dataDict)
dataDict = {
    "a":{
        "x": 1,
        "y": 2,
        "z": 3
        },
    "b":{
        "x": 1,
        "y": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "z": 3
        }
}  
value1=getFromDict(dataDict, ["a","z"])
print(value1)
value2=getFromDict(dataDict, ["b","y","z"])
print(value2)

 

1 شخص أعجب بهذا

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0

تسريع البحث ضمن القاموس؟ إن تخزين البيانات في القاموس ضمن بايثون يأخذ فضاء زني سريع جداً:

O(1)

حيث يتم تخزين المفاتيح باستعمال خوارزميات التقطيع hashing algoriths وهي أسرع من البحث في القوائم (n)O وحتى set.

لكنها تأخذ حجم تخزين أكبر نسبياً.

# سؤال غير واضح

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0

يمكنك الوصول لقيم المفاتيح في أي dictionary عن طريق إستخدام الدالة get الفرق الوحيد بين الdictionary العادي و المعقد هو قيم المفاتيح التي تكون في نفسها مفتاح لقيمة أخرى، راجع البرنامج التالي:

dataDict = {
    "a":{
        "x": 1,
        "y": 2,
        "z": 3
        },
    "b":{
        "x": 1,
        "y": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "z": 3
        }
}    

dataDict.get('b').get('y').get('z')

لاحظ أن طريقة النداء تتدرج من المفتاح الأول b و الذي يقود للمفتاح الثاني y والذي يقود للمفتاح الثالث z الذي قيمته تساوي 3.

print(dataDict['b'])
print(dataDict['b']['y']['z'])

{'x': 1, 'y': {'x': 1, 'y': 2, 'z': 3}, 'z': 3}
3

يمكننا أيضاً نداء المفتاح وحده (طريقة indexing)، لاحظ الإستدعاء لقيمة المفتاح b و التي تنتج الإجابة {'x': 1, 'y': {'x': 1, 'y': 2, 'z': 3}, 'z': 3} بذلك يمكننا أيضاً معاملتها بصورة dictionary بداخل dictionary كما في السطر الثاني والتي ستقود مباشرة للإجابة 3.

لاحظ أنه يمكنك الوصول للقيمة بالطريقتين لكن للإجابة على سؤال أي الطرق أسرع لابد من أن نحسب سرعة التنفيذ لكل من الطرق في الإجابات والمقارنة بين أزمانها، و هنالك عدة طرق لقياس الزمن أسهلها هي نداء العبارة timeit% قبل كل إستدعاء لأي دالة.

 

تمّ تعديل بواسطة Reem Elmahdi

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية

يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن