جدول تجزئة القاموس
تُعرف بنية جدول التجزئة الفعّالة للمفتاح/القيمة في Python باسم "المعجم". ويمكن كتابة محتوى القاموس كسلسلة من أزواج المفتاح/القيمة داخل أقواس { }، على سبيل المثال dict = {key1:value1, key2:value2, ... }. "القاموس الفارغ" هو مجرد زوج فارغ من الأقواس المعقوفة {}.
يتم استخدام أقواس مربّعة للبحث عن قيمة أو ضبطها في قاموس. على سبيل المثال، يبحث الأمر dict['foo'] عن القيمة ضمن المفتاح 'foo'. تعمل السلاسل والأرقام والمجموعات على أنّها مفاتيح، ويمكن أن يكون أيّ نوع قيمة. قد تعمل الأنواع الأخرى بشكل صحيح أو لا تعمل كعناوين (تعمل السلاسل والمجموعات بشكل جيد لأنّها غير قابلة للتغيير). يؤدي البحث عن قيمة غير متوفّرة في القاموس إلى ظهور خطأ KeyError. استخدِم "in" للتحقّق مما إذا كان المفتاح متوفّرًا في القاموس، أو استخدِم dict.get(key) الذي يعرض القيمة أو None إذا لم يكن المفتاح متوفّرًا (أو get(key, not-found) الذي يسمح لك بتحديد القيمة التي سيتم عرضها في حال عدم العثور على المفتاح).
## Can build up a dict by starting with the empty dict {} ## and storing key/value pairs into the dict like this: ## dict[key] = value-for-that-key dict = {} dict['a'] = 'alpha' dict['g'] = 'gamma' dict['o'] = 'omega' print(dict) ## {'a': 'alpha', 'o': 'omega', 'g': 'gamma'} print(dict['a']) ## Simple lookup, returns 'alpha' dict['a'] = 6 ## Put new key/value into dict 'a' in dict ## True ## print(dict['z']) ## Throws KeyError if 'z' in dict: print(dict['z']) ## Avoid KeyError print(dict.get('z')) ## None (instead of KeyError)
تتكرّر حلقة for في القاموس على مفاتيحه تلقائيًا. ستظهر المفاتيح بترتيب عشوائي. تُرجِع الطريقتان dict.keys() وdict.values() قوائم بالمفاتيح أو القيم بشكل صريح. هناك أيضًا دالة items() التي تعرض قائمة بمجموعات (المفتاح، القيمة)، وهي الطريقة الأكثر فعالية لفحص جميع بيانات المفتاح والقيمة في القاموس. يمكن تمرير جميع هذه القوائم إلى الدالة sorted().
## By default, iterating over a dict iterates over its keys. ## Note that the keys are in a random order. for key in dict: print(key) ## prints a g o ## Exactly the same as above for key in dict.keys(): print(key) ## Get the .keys() list: print(dict.keys()) ## dict_keys(['a', 'o', 'g']) ## Likewise, there's a .values() list of values print(dict.values()) ## dict_values(['alpha', 'omega', 'gamma']) ## Common case -- loop over the keys in sorted order, ## accessing each key/value for key in sorted(dict.keys()): print(key, dict[key]) ## .items() is the dict expressed as (key, value) tuples print(dict.items()) ## dict_items([('a', 'alpha'), ('o', 'omega'), ('g', 'gamma')]) ## This loop syntax accesses the whole dict by looping ## over the .items() tuple list, accessing one (key, value) ## pair on each iteration. for k, v in dict.items(): print(k, '>', v) ## a > alpha o > omega g > gamma
ملاحظة حول الاستراتيجية: من وجهة نظر الأداء، يُعدّ القاموس أحد أهم أدواتك، ويجب استخدامه كلما أمكن ذلك كطريقة سهلة لتنظيم البيانات. على سبيل المثال، يمكنك قراءة ملف سجلّ يبدأ كل سطر فيه بعنوان IP، وتخزين البيانات في قاموس باستخدام عنوان IP كمفتاح وقائمة الأسطر التي يظهر فيها كقيمة. بمجرد قراءة الملف بأكمله، يمكنك البحث عن أي عنوان IP وعرض قائمة السطور الخاصة به على الفور. يجمع القاموس البيانات المتفرقة وينظمها في مجموعات متماسكة.
تنسيقات النصوص المنطوقة
يعمل عامل % بشكلٍ ملائم لاستبدال القيم من قاموس بسلسلة حسب الاسم:
h = {} h['word'] = 'garfield' h['count'] = 42 s = 'I want %(count)d copies of %(word)s' % h # %d for int, %s for string # 'I want 42 copies of garfield' # You can also use str.format(). s = 'I want {count:d} copies of {word}'.format(h)
Del
يُجري عامل التشغيل del عمليات حذف. في أبسط الحالات، يمكن أن تزيل هذه العملية تعريف متغيّر، كما لو لم يتم تحديد هذا المتغيّر. يمكن أيضًا استخدام ديل في عناصر القائمة أو الشرائح لحذف هذا الجزء من القائمة وحذف الإدخالات من القاموس.
var = 6 del var # var no more! list = ['a', 'b', 'c', 'd'] del list[0] ## Delete first element del list[-2:] ## Delete last two elements print(list) ## ['b'] dict = {'a':1, 'b':2, 'c':3} del dict['b'] ## Delete 'b' entry print(dict) ## {'a':1, 'c':3}
الملفات
تفتح الدالة open() معرّف ملف وتُرجعه، ويمكن استخدامه لقراءة ملف أو كتابته بالطريقة المعتادة. يفتح الرمز f = open('name', 'r') الملف في المتغيّر f، وهو جاهز لإجراء عمليات القراءة، ويمكنك استخدام f.close() عند الانتهاء. بدلاً من "r"، استخدِم "w" للكتابة، و"a" للإلحاق. تعمل حلقة for-loop العادية مع الملفات النصية، وتتم إعادة تشغيلها في سطور الملف (لا يعمل هذا إلا مع الملفات النصية، وليس الملفات الثنائية). إنّ أسلوب حلقة for هي طريقة بسيطة وفعّالة للاطّلاع على جميع الأسطر في ملف نصي:
# Echo the contents of a text file f = open('foo.txt', 'rt', encoding='utf-8') for line in f: ## iterates over the lines of the file print(line, end='') ## end='' so print does not add an end-of-line char ## since 'line' already includes the end-of-line. f.close()
تتميز قراءة سطر واحد في كل مرة بميزة رائعة وهي أنّه لا يجب أن يتلاءم كل الملف مع الذاكرة في وقت واحد، ما يُعدّ أمرًا مفيدًا إذا كنت تريد الاطّلاع على كل سطر في ملف بسعة 10 غيغابايت بدون استخدام 10 غيغابايت من الذاكرة. تقرأ الطريقة f.readlines() الملف بأكمله في الذاكرة وتعرض محتوياته كقائمة سطوره. تقرأ الطريقة f.read() الملف بأكمله في سلسلة واحدة، والتي يمكن أن تكون طريقة سهلة للتعامل مع النص مرة واحدة، كما هو الحال مع التعبيرات العادية التي ستراها لاحقًا.
للكتابة، تعد طريقة f.write(string) أسهل طريقة لكتابة البيانات في ملف إخراج مفتوح. أو يمكنك استخدام "print" مع ملف مفتوح مثل "print(string, file=f)".
يونيكود الملفات
لقراءة الملفات التي تم ترميزها باستخدام ترميز Unicode وكتابتها، استخدِم وضع 't' وحدِّد ترميزًا صراحةً:
with open('foo.txt', 'rt', encoding='utf-8') as f: for line in f: # here line is a *unicode* string with open('write_test', encoding='utf-8', mode='wt') as f: f.write('\u20ACunicode\u20AC\n') # €unicode€ # AKA print('\u20ACunicode\u20AC', file=f) ## which auto-adds end='\n'
تطوير تدريجي للتمرين
عند إنشاء برنامج بايثون، لا تكتب كل شيء في خطوة واحدة. بدلاً من ذلك، حدِّد إنجازًا أوليًا فقط، مثلاً "حسنًا، الخطوة الأولى هي استخراج قائمة الكلمات". اكتب الرمز البرمجي للوصول إلى هذا الإنجاز، واطبع هياكل البيانات في تلك المرحلة، ثم يمكنك استخدام sys.exit(0) حتى لا يتم تشغيل البرنامج إلى أجزائه غير المكتملة. بمجرد عمل رمز المعلم الرئيسي، يمكنك العمل على رمز المعلم الرئيسي التالي. إنّ التمكّن من الاطّلاع على نسخة مطبوعة من متغيّراتك في حالة معيّنة يمكن أن يساعدك في التفكير في كيفية تحويل هذه المتغيّرات للوصول إلى الحالة التالية. تعمل لغة بايثون بسرعة كبيرة مع هذا النمط، ما يتيح لك إجراء تغيير بسيط وتشغيل البرنامج لمعرفة كيفية عمله. يمكنك الاستفادة من هذا الوقت القصير لإنشاء برنامجك من خلال خطوات بسيطة.
تمرين: wordcount.py
من خلال الجمع بين جميع مواد Python الأساسية - السلاسل، القوائم، الإملاءات، الصفوف، الملفات -- جرّب تمرين الملخص wordcount.py في التمارين الأساسية.