اذهب إلى المحتوى

السؤال

نشر

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


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 من القاموس من خلال قائمة المفاتيح السابقة؟ هل توجد مكتبة / دولة قياسية تقوم بهذا الأمر بشكل سريع؟

Recommended Posts

  • 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)

 

  • 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

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...