الإملاء والملف في بايثون

جدول تجزئة الإملاء

يُطلق على بنية جدول تجزئة المفتاح/القيمة الفعالة في بايثون اسم "الإملاء". يمكن كتابة محتوى الإملاء كسلسلة من أزواج المفتاح:القيمة بين الأقواس المعقوفة { }، على سبيل المثال: 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)

إملاء باستخدام المفاتيح 'a' 'o' 'g'

تتكرر التكرار الحلقي 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" بالحذف. في أبسط الحالات، يمكنها إزالة تعريف المتغير، كما لو لم يتم تعريف هذا المتغير. يمكن أيضًا استخدام 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}

Files

تفتح الدالة open() وترجع مؤشر ملف يمكن استخدامه لقراءة ملف أو كتابته بالطريقة المعتادة. التعليمة البرمجية f = open('name', 'r') تفتح الملف في المتغير f، وتكون جاهزة لعمليات القراءة، وتستخدم f.Close() عند الانتهاء. بدلاً من "r"، استخدم "w" للكتابة، و"a" للإلحاق. يعمل التكرار الحلقي القياسي مع الملفات النصية، والتكرار عبر سطور الملف (يعمل هذا فقط للملفات النصية، وليس الملفات الثنائية). يعد أسلوب for-loop طريقة بسيطة وفعالة لإلقاء نظرة على جميع الأسطر في ملف نصي:

  # 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

من خلال الجمع بين جميع مواد بايثون الأساسية -- السلاسل والقوائم والإملاء والصفوف والملفات -- جرّب ملخص تمرين wordcount.py في التمارين الأساسية.