إنشاء وتحديث أزواج المفاتيح والقيم
سنتعلم الآن كيف نضيف أزواج مفتاح وقيمة جديدة إلى القاموس، مثلما نحتاج عند تسجيل ما يشتريه العميل.
قبل القواميس، لنراجع سريعًا طريقة إضافة عناصر إلى قائمة. شغّل البرنامج:
cart = []
cart.append('dog')
cart.append('box')
print(cart)
بسيط. ويمكننا أيضًا تغيير القيمة الموجودة عند فهرس معين واستبدالها بقيمة أخرى:
cart = ['dog', 'cat']
cart[1] = 'box'
print(cart)
ماذا لو حاولنا استخدام الإسناد بالفهرس لإنشاء عناصر القائمة من البداية؟ نعرف أننا نريد cart[0] مساوية لـ'dog' وcart[1] مساوية لـ'box'، فلنجرب أن نقول ذلك مباشرة:
cart = []
cart[0] = 'dog'
cart[1] = 'box'
print(cart)
هذا غير مسموح مع القوائم: الإسناد باستخدام الفهرس يعمل فقط مع فهرس صالح موجود بالفعل.
لكن القواميس مختلفة. جرّب:
quantities = {}
quantities['dog'] = 500
quantities['box'] = 2
print(quantities)
لاحظ أن {} تعني قاموسًا فارغًا، أي لا يحتوي على أي أزواج مفتاح وقيمة. وهي تشبه [] للقائمة الفارغة و"" للنص الفارغ.
عندما تسند قيمة إلى مفتاح غير موجود في قاموس، يُنشأ زوج المفتاح والقيمة الجديد.
هذا بالضبط ما نحتاجه. سواء أراد العميل 500 كلب أو خمسة ملايين، نستطيع وضع المعلومة مباشرة في قاموس الكميات.
اكتب دالة عامة اسمها buy_quantity(quantities, item, quantity) تضيف زوجًا جديدًا من المفتاح والقيمة إلى قاموس quantities:
def buy_quantity(quantities, item, quantity):
...
def test():
quantities = {}
buy_quantity(quantities, 'dog', 500)
check_result(quantities, {'dog': 500})
buy_quantity(quantities, 'box', 2)
check_result(quantities, {'dog': 500, 'box': 2})
test()
يجب أن تعدّل buy_quantity القاموس الذي استلمته مباشرة، ولا تحتاج إلى return أو print. يمكنك افتراض أن item غير موجود مسبقًا في quantities.
جسم الدالة يحتاج سطرًا واحدًا فقط. حوّل الفكرة المحددة quantities['dog'] = 500 إلى صيغة عامة تستخدم المتغيرين item وquantity من دون وضعهما بين علامات اقتباس.
The body of
buy_quantityonly needs one simple line of code.It's similar to some of the lines in the previous step, but with variables instead of hardcoded values.
Be careful with quotes!
'dog'is an example of a value foritem.What would be an example of a value for
quantity?For
'dog', it was500above.You're making a generic version of
quantities['dog'] = 500.The
quantitiespart is fine as is.Also keep the
[]and=.تذكر أن
itemis a variable,'item'is a string literal.Replace
'dog'withitem.Replace
500withquantity.Don't use
'item'or'quantity', use the variablesitemandquantitydirectly.
أحسنت! جرّب الدالة الآن بصورة تفاعلية:
def buy_quantity(quantities, item, quantity):
quantities[item] = quantity
def test():
quantities = {}
for _ in range(3):
print('What would you like to buy?')
item = input()
print('How many?')
quantity = int(input())
buy_quantity(quantities, item, quantity)
print("OK, here's your cart so far:")
print(quantities)
test()
انتبه إلى الجزء int(input()): الدالة input() تعيد نصًا، بينما quantity يجب أن تكون عددًا صحيحًا. إذا أدخل المستخدم شيئًا ليس رقمًا فسيحدث خطأ، وهذا مقبول في هذه المرحلة.
شكرًا للتسوق معنا! لنحسب الآن المبلغ الذي أنفقته على كل نوع من المنتجات على حدة.
كتبنا سابقًا total_cost(quantities, prices) التي تعيد رقمًا واحدًا يمثل الإجمالي الكلي. الآن اكتب total_cost_per_item(quantities, prices) بحيث تعيد قاموسًا جديدًا فيه التكلفة الإجمالية لكل عنصر:
def total_cost_per_item(quantities, prices):
totals = {}
for item in quantities:
___ = quantities[item] * prices[item]
return totals
check_result(
total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}),
{'apple': 6},
)
check_result(
total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}),
{'dog': 50000, 'box': 10},
)
املأ الجزء ___. في الاختبار الأول اشترى العميل تفاحتين وسعر الواحدة 3، لذلك يجب أن يحتوي القاموس الجديد على 'apple': 6. المفتاح هو item، والقيمة هي quantities[item] * prices[item]، والقاموس الذي نبنيه هو totals.
You only need to fill in the
___part.But if you want, you could also just put a variable name there, and then add a new line below it.
Look at the tests with
check_result. In the first example, the expected output is{'apple': 6}. Why?Because the customer bought 2 apples, and each apple costs 3, so the total cost is
2 * 3 = 6.The
'box': 5part is ignored because the customer didn't buy any boxes. It just means that the price of a box is 5.You need to add a new key-value pair to a dictionary.
Identify the dictionary, the key, and the value.
They are all present in the given code already.
The value is the total cost for that item, which is the quantity multiplied by the price.
i.e.
quantities[item] * prices[item].The dictionary is the thing that this function creates, builds, and returns.
i.e.
totals.Note how
'apple'is a key in all three dictionaries in that test.i.e. the dictionaries
quantities,prices, andtotals.
ممتاز! لنرجع إلى مثال الترجمة.
لنفترض أن لدينا قاموسًا من الإنجليزية إلى الفرنسية، وقاموسًا آخر من الفرنسية إلى الألمانية. استخدمهما لإنشاء قاموس جديد من الإنجليزية إلى الألمانية:
def make_english_to_german(english_to_french, french_to_german):
...
check_result(
make_english_to_german(
{'apple': 'pomme', 'box': 'boite'},
{'pomme': 'apfel', 'boite': 'kasten'},
),
{'apple': 'apfel', 'box': 'kasten'},
)
أنشئ قاموسًا فارغًا، ومرّ على الكلمات الإنجليزية في القاموس الأول. قيمة الكلمة الإنجليزية في القاموس الأول هي الكلمة الفرنسية، وهذه الكلمة الفرنسية هي مفتاح في القاموس الثاني، ومنه تحصل على الكلمة الألمانية. أضف النتيجة إلى القاموس الجديد ثم أعده في النهاية.
You need to create a new dictionary and fill it with key-value pairs depending on the two input dictionaries.
You've seen code that does this before.
Specifically the previous step. The overall structure you want is similar to
total_cost_per_item.Start by creating a new empty dictionary.
Return the dictionary at the end. Then fill in the code in between.
You need a
forloop.The line
totals[item] = quantities[item] * prices[item]from the previous step is close to what you need.You don't need to multiply anything with
*, the names are different, and there's another difference in logic.Think about what the keys and values of the new dictionary should be.
The keys should be English words, so they should come from the first dictionary.
The values should be German words, so they should come from the second dictionary.
Specifically the keys of your dictionary should be the keys of the first dictionary.
And the values of your dictionary should be the values of the second dictionary.
What about the values of the first dictionary and the keys of the second dictionary? They're important.
Look at the French words
'pomme'and'boite'in the example test.The values of the first input dictionary are the keys of the second input dictionary.
عمل رائع!
اكتب الآن دالة تأخذ قاموسًا وتعيد قاموسًا جديدًا بعد تبديل المفاتيح والقيم؛ أي يتحول الزوج a: b إلى b: a:
def swap_keys_values(d):
...
check_result(
swap_keys_values({'apple': 'pomme', 'box': 'boite'}),
{'pomme': 'apple', 'boite': 'box'},
)
لا تعدّل القاموس الأصلي d. أنشئ قاموسًا فارغًا جديدًا، ومرّ على مفاتيح d. لكل مفتاح، احصل على قيمته، ثم استخدم هذه القيمة كمفتاح جديد واجعل المفتاح القديم هو القيمة الجديدة.
Don't modify the input dictionary
d.You need to create a new dictionary and fill it with key-value pairs depending on the input dictionary.
You've done this in the previous exercise. The overall structure you want is similar to
make_english_to_german.It's actually even simpler, it just might feel weird.
Start by creating a new empty dictionary. Return the dictionary at the end. Put a
forloop in between.Think about what the keys and values of the new dictionary should be.
There's only one possible thing for you to loop over.
Use each key in the input dictionary
dto get the corresponding value.
ممتاز!
لكن من المهم أن تعرف أين يمكن أن تفشل فكرة تبديل المفاتيح والقيم. كما يمكن أن يكون لمنتجين في المتجر السعر نفسه، يمكن لكلمتين إنجليزيتين أن تكون لهما الترجمة الفرنسية نفسها.
إذا احتوى القاموس الأصلي على قيم مكررة، فماذا يحدث عندما تجعل هذه القيم مفاتيح؟ مفاتيح القاموس يجب أن تكون فريدة، لذلك ستضيع بعض البيانات.
مثلًا، الكلمة الفرنسية 'avocat' قد تعني avocado أو lawyer. من السهل ترجمة كل كلمة إنجليزية إلى الفرنسية، لكن عند رؤية 'avocat' وحدها لا نعرف أي معنى إنجليزي كان المقصود.
حاول توقع ما سيطبعه الكود التالي قبل تشغيله:
def swap_keys_values(d):
new_dict = {}
for key in d:
new_dict[d[key]] = key
return new_dict
print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'}))
print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'}))
تعتمد النتيجة على ترتيب المفاتيح في القاموس الأصلي. إذا لم يكن السبب واضحًا، فتتبّع تنفيذ الكود خطوة بخطوة وراقب متى تُكتب كل قيمة داخل القاموس الجديد.
ومع ذلك توجد حالات كثيرة تستطيع فيها التأكد من أن قيم القاموس الأصلية فريدة، وعندها يكون «عكس» القاموس منطقيًا. رأينا سابقًا هذا المثال:
def substitute(string, d):
result = ""
for letter in string:
result += d[letter]
return result
plaintext = 'helloworld'
encrypted = 'qpeefifmez'
letters = {'h': 'q', 'e': 'p', 'l': 'e', 'o': 'f', 'w': 'i', 'r': 'm', 'd': 'z'}
reverse = {'q': 'h', 'p': 'e', 'e': 'l', 'f': 'o', 'i': 'w', 'm': 'r', 'z': 'd'}
check_result(substitute(plaintext, letters), encrypted)
check_result(substitute(encrypted, reverse), plaintext)
والآن نستطيع إنشاء reverse تلقائيًا:
reverse = swap_keys_values(letters)
لكي ينجح هذا يجب أن تكون كل القيم في letters فريدة. إذا استُبدل كل من 'h' و'j' بالقيمة 'q' أثناء التشفير، فلن توجد طريقة عند فك التشفير لمعرفة هل 'qpeef' كانت أصلًا 'hello' أم 'jello'.
تهانينا! وصلت إلى نهاية الجزء المتاح حاليًا من الدورة. سيُضاف المزيد لاحقًا.