المتغيرات في بايثون وكيفية التعامل مع التراكيب - سلسلة بايثونات لتعلم لغة البايثون

المتغيرات في بايثون وكيفية التعامل مع التراكيب – سلسلة بايثونات لتعلم لغة البايثون

أهلًا وسهلًا بك عزيزي القارئ في ثالث مقالات سلسة بايثونات لتعلم لغة البايثون المُوجهة بشكل أساسي لكل مبتدئ في تعلم البايثون والمهتمين بشكل عام. هذا المقال بعنوان المتغيرات في بايثون وكيفية التعامل مع التراكيب، وفيه نُوضح كيفية تعريف المتغيرات في بايثون وكيفية استخدام التراكيب الأربعة الأساسية في بايثون. للإطلاع على كافة مقالات السلسلة من خلال الروابط التالية:

  1. لغة بايثون للمبتدئين – سلسلة بايثونات لتعلم البايثون والانطلاق في عالم البرمجة.
  2. النصوص في بايثون.
  3. المتغيرات والتراكيب في بايثون.
  4. جُمل التحكم في بايثون.
  5. الدوال والوحدات بايثون.
  6. مُعالجة الأخطاء في بايثون.
  7. البرمجة الكائنية في بايثون.

دالة الطباعة في بايثون

قبل البدء بموضوع المتغيرات في بايثون وما هي التراكيب التي يُمكننا التعامل معها، من المهم التعرف على دالة الطباعة في بايثون والتي من خلالها يُمكننا طباعة المخرجات على مُفسر البايثون. البايثون لديها وظيفة خاصة للطباعة، ونقصد بالطباعة هنا أي الإخراج على شاشة الأوامر أو الطرفية وتسمى print:

print("I'm Python. Nice to meet you!")  # => I'm Python. Nice to meet you!

يتم طباعة سطر جديد تلقائيا عند استخدام الوظيفة print. يُمكننا استخدام المُعطى end لتغيير هذا الأمر وتحديد النص أو الرمز الذي نريده بدلا من السطر الجديد:

print("Hello, World", end="!")  # => Hello, World!

نستخدم الدالة input للإدخال وللحصول على مدخلات من شاشة الأوامر:

input_string_var = input("Enter some data: ") # Returns the data as a string

ملاحظة/ في النُسخ القديمة من البايثون، الوظيفة input كانت تُسمى raw_input.

تعريف المتغيرات في بايثون

لا يوجد في البايثون تعريفات، بمعنى أنه لا نُحدد نوع المتغير، ويتم إعطاء المتغير قيمة بشكل مباشر. الطريقة المتعارف عليها في تسمية المتغيرات هي الأحرف الصغيرة مع التسطير السفلي:

some_var = 5

some_var  # => 5

محاولة استخدام متغير لم يأخذ قيمة مسبقاً ينتج عنه خطأ، سنشرح كيفية معالجة الأخطاء في مقالات قادمة.

some_unknown_var  # Raises a NameError

التراكيب في بايثون

يُوجد في البايثون أربعة تراكيب أساسية، تتمثل في:

  1. القوائم
  2. Tuple (لم نجد ترجمة عربية مُتفق عليها).
  3. المجموعات
  4. القواميس

سنتناول كل واحد منهم بالشرح كما يلي:

القوائم في بايثون

القوائم تشبه المصفوفات في لغات البرمجة الأخرى، ولها استخدامات أساسية وعديدة في لغة البايثون والمكتبات المعيارية فيها:

li = [] #> empty list

other_li = [4, 5, 6]

نستخدم الدالة append لإضافة عناصر في نهاية القائمة:

li.append(1)    # li is now [1]

li.append(2)    # li is now [1, 2]

li.append(4)    # li is now [1, 2, 4]

li.append(3)    # li is now [1, 2, 4, 3]

الدالة pop تُستخدم لحذف العناصر من اخر القائمة:

li.pop()        # => 3 and li is now [1, 2, 4]

li.append(3)    # li is now [1, 2, 4, 3] again.

يُمكننا التعامل مع القائمة كما نتعامل مع المصفوفة من حيث الوصول لعناصرها وذلك عبر استخدام الفهرس index:

li[0]   # => 1

li[-1]  # => 3

اذا مررنا قيمة فهرس خارج حدود القائمة سينتج عن ذلك خطأ من نوع IndexError:

li[4]  # Raises an IndexError

يُمكننا استخدام نطاق range للحصول على جزء أكبر من القائمة بحيث نحدد فهرس البداية وفهرس النهاية كما في المثال التالي:

li[1:3]   # => [2, 4]

ملاحظة/ العنصر الذي يقع في فهرس النهاية غير مشمول في القيمة المرجعة، حيث يُعتبر النمط المستخدم هنا هو نمط نطاق مغلق-مفتوح.

في حال عدم استخدام فهرس النهاية ستكون النتيجة المُرجعة هي ابتداءً من فهرس البداية وحتى آخر عنصر في القائمة:

li[2:]    # => [4, 3]

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

li[:3]    # => [1, 2, 4]

يُمكننا تحديد ما يُسمى بـ step في النطاق الذي نحدده، وهي تُمثل عدد خطوات التجاوز. فمثلًا، لاختيار عنصر كل خطوتين ابتداء من العنصر الأول في القائمة نكتب ما يلي:

li[::2]   # =>[1, 4]

لارجاع كامل المصفوفة بطريقة عكسية وبسطر واحد:

li[::-1]  # => [3, 4, 2, 1]

القاعدة العامة للاستعلامات السابقة في القوائم هي كالتالي:

# li[start:end:step]

النسخ العميق (Deep Copy)

li2 = li[:]  # => li2 = [1, 2, 4, 3]

li2 is li #> False

في حال قمنا بفحص المساواة باستخدام عملية is كالتالي: (li2 is li) ستكون النتيجة False.

لحذف عنصر من القائمة موجود في فهرس معين نستخدم الدالة del:

del li[2]  # li is now [1, 2, 3]

لحذف أول عنصر في القائمة يساوي القيمة المدخلة في وظيفة remove ونُمرر لها قيمة العنصر المُراد حذفه:

li.remove(2)  # li is now [1, 3]

li.remove(2)  # ValueError لأن القيمة غير موجودة

لإضافة عنصر جديد في مكان معين من القائمة نستخدم الدالة insert ونمرر لها فهرس العنصر الجديد:

li.insert(1, 2)  # li is now [1, 2, 3] again

للحصول على فهرس أول عنصر في القائمة يساوي القيمة المعطاة نستخدم الدالة index:

li.index(2)  # => 1

li.index(4)  # ValueError لأن القيمة غير موجودة

يُمكننا إضافة قائمة بداخل قائمة أخرى وإرجاع النتيجة كقائمة جديدة وذلك عن طريق استخدام عملية الجمع + كما يلي:

li + other_li  # => [1, 2, 3, 4, 5, 6]

يُمكن تنفيذ نفس الأمر عن طريق استخدام الدالة extend والتي تعمل على تمديد قائمة وإضافة قائمة إليها:

li.extend(other_li)  # Now li is [1, 2, 3, 4, 5, 6]

قد نحتاج التأكد من وجود عنصر معين في قائمة ما، لذلك يُمكننا الاستعانة بالعملية المنطقية in التي تعمل على فحص وجود قيمة في القائمة:

1 in li  # => True

كما ذكرنا في درس التعامل مع النصوص في بايثون، يُمكننا ايضا استخدام الدالة len للحصول على حجم القائمة (عدد العناصر التي بها):

len(li)  # => 6

Tuple

نوع البيانات Tuple يُشبه القائمة ولكنه غير قابل للتعديل (ثابتة-immutable):

tup = (1, 2, 3)

tup[0]      # => 1

tup[0] = 3  # Raises a TypeError

لاحظ أنه في حالة وجود عنصر واحد في tuple لابد من وضع فاصلة عادية بعد العنصر، أما في حالة وجود أكثر من عنصر فتصبح الفاصلة الأخيرة إضافية:

type((1))   # => <class 'int'>

type((1,))  # => <class 'tuple'>

type(())    # => <class 'tuple'>

يُمكننا تنفيذ أغلب عمليات القوائم على Tuples:

len(tup)         # => 3

tup + (4, 5, 6)  # => (1, 2, 3, 4, 5, 6)

tup[:2]          # => (1, 2)

2 in tup         # => True

يُمكن تفريغ unpacking محتويات Tuples وكذلك القوائم في متغيرات كما في الأمثلة التالية:

a, b, c = (1, 2, 3)  # a = 1, b = 2, c = 3

a, *b, c = (1, 2, 3, 4)  # a = 1, b = [2, 3], c = 4

من خلال tuple يُمكننا تبديل قيم المتغيرات بطريقة سهلة وسريعة:

e, d = d, e  # d = 5, e = 4

القواميس

القواميس هي نوع بيانات في البايثون يُشبه الهاش hash في لغات برمجة أخرى، وهي عبارة عن سلسلة من العناصر وكل عنصر عبارة عن مفتاح وقيمة key & value. يُمكن اعتبار المفاتيح مؤشرات بحيث كل مفتاح يؤشر إلى قيمة خاصة به. لتعريف قاموس فارغ:

empty_dict = {}

يُمكننا تعريف قاموس بقيم مسبقة:

filled_dict = {"one": 1, "two": 2, "three": 3}

لاحظ أن المفاتيح في القواميس لابد أن يكون نوع بياناتها ثابت (immutable) وذلك لضمان الحصول على مفتاح ثابت (لا تتغير قيمته).

أنواع البيانات الثابتة والتي من الممكن استخدامها هي int , float, string, tuple.

invalid_dict = {[1,2,3]: "123"}  # => Raises a TypeError: unhashable type: 'list'

valid_dict = {(1,2,3):[1,2,3]}   # Values can be of any type, however.

للوصول لقيمة مُرتبطة بمفتاح معين في القاموس نستخدم الأقواس المعكوفة ونُمرر لها المفتاح كما يلي:

filled_dict["one"]  # => 1

نستخدم الدالة keys للحصول على مفاتيح القاموس على شكل قائمة (الترتيب في القواميس غير ثابت):

list(filled_dict.keys())  # => ["three", "two", "one"]

نستخدم الدالة vlaues للحصول على قيم القاموس على شكل قائمة:

list(filled_dict.values())  # => [3, 2, 1]

للتأكد من وجود مفتاح قاموس معين:

"one" in filled_dict  # => True

1 in filled_dict      # => False

في حالة استخدام مفتاح غير موجود للبحث في قاموس، فإن ذلك ينتج خطأ:

filled_dict["four"]  # KeyError

لتجنب ظهور خطأ KeyError يُمكننا الاعتماد على وظيفة get، حيث تُرجع قيمة فارغة عندما لا يكون المفتاح المُمرر لها موجودًا في القاموس:

filled_dict.get("one")      # => 1

filled_dict.get("four")     # => None

تدعم وظيفة get إعادة قيمة تلقائية في حالة عدم وجود المفتاح:

filled_dict.get("one", 4)   # => 1

filled_dict.get("four", 4)  # => 4

تقوم وظيفة setdefault بالإضافة على القاموس في حالة عدم وجود المفتاح المعطى:

filled_dict.setdefault("five", 5)  # filled_dict["five"] is set to 5

filled_dict.setdefault("five", 6)  # filled_dict["five"] is still 5

للإضافة على القاموس:

filled_dict.update({"four":4})  # => {"one": 1, "two": 2, "three": 3, "four": 4}

filled_dict["four"] = 4         # طريقة أخرى

لحذف المفتاح من القاموس يُمكننا استخدام الدالة del:

del filled_dict["one"]  # Removes the key "one" from filled dict

المجموعات

لتعريف مجموعة فارغة نستخدم الباني الخاص بالمجموعات كما يلي:

empty_set = set()

some_set = {1, 1, 2, 2, 3, 4}  # some_set is now {1, 2, 3, 4}

نوع البيانات الخاص بعناصر المجموعات لابد أن يكون ثابتة immutable وهذا يعني أنه لا يُمكن استخدام عناصر من نوع القائمة في المجموعات:

invalid_set = {[1], 1}  # => Raises a TypeError: unhashable type: 'list'

valid_set = {(1,), 1}

للإضافة على المجموعة نستخدم الدالة add:

filled_set.add(5)  # filled_set is now {1, 2, 3, 4, 5}

إجراء عملية التقاطع بين مجموعتين نستخدم العملية & :

other_set = {3, 4, 5, 6}

filled_set & other_set  # => {3, 4, 5}

إجراء عملية الاتحاد بين مجموعتين نستخدم العملية | :

filled_set | other_set  # => {1, 2, 3, 4, 5, 6}

إجراء عملية الطرح بين مجموعتين:

{1, 2, 3, 4} - {2, 3, 5}  # => {1, 4}

لإجراء عملية فرق التماثل بين مجموعتين:

{1, 2, 3, 4} ^ {2, 3, 5}  # => {1, 4, 5}

لفحص إذا كانت المجموعة على الشمال هي مجموعة تحتوي المجموعة على اليمين أم لا:

{1, 2} >= {1, 2, 3} # => False

عكس المثال السابق:

{1, 2} <= {1, 2, 3} # => True

فحص وجود قيمة في مجموعة:

2 in filled_set   # => True

10 in filled_set  # => False

إلى هنا ينتهي هذا المقال الخاص بشرح المتغيرات والتراكيب في بايثون. ذكرنا في هذا المقال كيفية تعريف المتغيرات في بايثون، وكيف نتعامل مع التراكيب فيها. نتمنى أن نكون وُفقنا في إيصال المعلومة بالشكل الصحيح، ونسعد بأي ملاحظة في التعليقات. كما نتمنى منكم مشاركة مقالات السلسلة في منصات التواصل الاجتماعي مثل تويتر وفيسبوك حتى تعم الفائدة.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *