استخدام تدوين Python list comprehensions

اعمال

في Python ، من السهل استخدام تدوين list comprehensions عند إنشاء قائمة جديدة.(List comprehensions)

في هذه المقالة ، سنناقش أولاً ما يلي

  • النوع الأساسي من تدوين قائمة الفهم
  • قائمة تدوين الفهم مع التفريع الشرطي بواسطة if
  • الدمج مع العوامل الثلاثية (إذا كانت المعالجة شبيهة)
  • zip()وenumerate()الجمع مع هؤلاء
  • تدوين قائمة متداخلة

بعد ذلك ، سنشرح مجموعة تدوين القائمة باستخدام نموذج التعليمات البرمجية.

  • تعيين تدوين التضمين(Set comprehensions)
  • تدوين إدراج القاموس(Dict comprehensions)
  • نوع المولد(Generator expressions)

النوع الأساسي من تدوين قائمة الفهم

تتم كتابة تدوين القائمة على النحو التالي.

[Expression for Any Variable Name in Iterable Object]

يأخذ كل عنصر من عناصر كائن قابل للتكرار مثل قائمة أو مجموعة أو نطاق بواسطة اسم متغير عشوائي ويقيمه بتعبير. يتم إرجاع قائمة جديدة بنتيجة التقييم كعنصر.

يتم إعطاء مثال مع معادل للبيان.

squares = [i**2 for i in range(5)]
print(squares)
# [0, 1, 4, 9, 16]
squares = []
for i in range(5):
    squares.append(i**2)

print(squares)
# [0, 1, 4, 9, 16]

يمكن إجراء نفس العملية باستخدام map () ، لكن يفضل استخدام طريقة قائمة الفهم لبساطتها ووضوحها.

قائمة تدوين الفهم مع التفريع الشرطي بواسطة if

التفرع الشرطي مع إذا كان ممكنًا أيضًا. اكتب إذا في postfix على النحو التالي.

[Expression for Any Variable Name in Iterable Object if Conditional Expression]

يتم فقط تقييم عناصر الكائن القابل للتكرار الذي يكون تعبيره الشرطي صحيحًا بواسطة التعبير ، ويتم إرجاع قائمة جديدة تكون عناصرها النتيجة.

يمكنك استخدام أي اسم متغير في التعبير الشرطي.

يتم إعطاء مثال مع معادل للبيان.

odds = [i for i in range(10) if i % 2 == 1]
print(odds)
# [1, 3, 5, 7, 9]
odds = []
for i in range(10):
    if i % 2 == 1:
        odds.append(i)

print(odds)
# [1, 3, 5, 7, 9]

يمكن إجراء نفس العملية باستخدام عامل التصفية () ، ولكن يفضل استخدام طريقة التعرف على القائمة نظرًا لبساطتها ووضوحها.

الدمج مع العوامل الثلاثية (إذا كانت المعالجة شبيهة)

في المثال أعلاه ، تتم معالجة العناصر التي تفي بالمعايير فقط ، ويتم استبعاد العناصر التي لا تفي بالمعايير من القائمة الجديدة.

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

في بايثون ، يمكن كتابة العامل الثلاثي على النحو التالي

Value When True if Conditional Expression else Value When False

يستخدم هذا في جزء التعبير من تدوين قائمة الفهم كما هو موضح أدناه.

[Value When True if Conditional Expression else Value When False for Any Variable Name in Iterable Object]

يتم إعطاء مثال مع معادل للبيان.

odd_even = ['odd' if i % 2 == 1 else 'even' for i in range(10)]
print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']
odd_even = []
for i in range(10):
    if i % 2 == 1:
        odd_even.append('odd')
    else:
        odd_even.append('even')

print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']

من الممكن أيضًا كتابة تعبيرات باستخدام أسماء متغيرات عشوائية لقيم الصواب والخطأ.

إذا تم استيفاء الشرط ، تتم بعض المعالجة ، وإلا فإن قيمة الكائن الأصلي القابل للتكرار تُترك دون تغيير.

odd10 = [i * 10 if i % 2 == 1 else i for i in range(10)]
print(odd10)
# [0, 10, 2, 30, 4, 50, 6, 70, 8, 90]

الجمع مع الرمز البريدي () والعدد ()

الوظائف المفيدة التي تُستخدم غالبًا في عبارة for تتضمن zip () ، الذي يجمع العديد من المتكررات ، و enumerate () ، التي تُرجع قيمة مع فهرسها.

بالطبع ، من الممكن استخدام zip () والعدد () مع تدوين list comprehension. إنه ليس بناء جملة خاصًا ، وليس من الصعب أن تفكر في التطابق مع عبارة for.

مثال على zip ().

l_str1 = ['a', 'b', 'c']
l_str2 = ['x', 'y', 'z']

l_zip = [(s1, s2) for s1, s2 in zip(l_str1, l_str2)]
print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]
l_zip = []
for s1, s2 in zip(l_str1, l_str2):
    l_zip.append((s1, s2))

print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]

مثال على تعداد ().

l_enu = [(i, s) for i, s in enumerate(l_str1)]
print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]
l_enu = []
for i, s in enumerate(l_str1):
    l_enu.append((i, s))

print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]

الفكرة هي نفسها كما كانت من قبل عند استخدام if.

l_zip_if = [(s1, s2) for s1, s2 in zip(l_str1, l_str2) if s1 != 'b']
print(l_zip_if)
# [('a', 'x'), ('c', 'z')]

يمكن أيضًا استخدام كل عنصر لحساب عنصر جديد.

l_int1 = [1, 2, 3]
l_int2 = [10, 20, 30]

l_sub = [i2 - i1 for i1, i2 in zip(l_int1, l_int2)]
print(l_sub)
# [9, 18, 27]

تدوين قائمة متداخلة

مثل nesting for loops ، يمكن أيضًا أن يتداخل تدوين list comprehension.

[Expression for Variable Name 1 in Iterable Object 1
    for Variable Name 2 in Iterable Object 2
        for Variable Name 3 in Iterable Object 3 ... ]

للراحة ، تمت إضافة فواصل الأسطر والمسافات البادئة ، ولكنها ليست مطلوبة لقواعد اللغة ؛ يمكن أن تستمر في سطر واحد.

يتم إعطاء مثال مع معادل للبيان.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

flat = [x for row in matrix for x in row]
print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
flat = []
for row in matrix:
    for x in row:
        flat.append(x)

print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

من الممكن أيضًا استخدام متغيرات متعددة.

cells = [(row, col) for row in range(3) for col in range(2)]
print(cells)
# [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]

يمكنك أيضًا إجراء التفريع الشرطي.

cells = [(row, col) for row in range(3)
         for col in range(2) if col == row]
print(cells)
# [(0, 0), (1, 1)]

من الممكن أيضًا التفرع الشرطي لكل كائن قابل للتكرار.

cells = [(row, col) for row in range(3) if row % 2 == 0
         for col in range(2) if col % 2 == 0]
print(cells)
# [(0, 0), (2, 0)]

تعيين تدوين التضمين(Set comprehensions)

يؤدي تغيير الأقواس المربعة [] في قائمة الفهم إلى أقواس متعرجة {} إلى إنشاء مجموعة (كائن من نوع المجموعة).

{Expression for Any Variable Name in Iterable Object}
s = {i**2 for i in range(5)}

print(s)
# {0, 1, 4, 9, 16}

تدوين إدراج القاموس(Dict comprehensions)

يمكن أيضًا إنشاء القواميس (كائنات من نوع ديكت) باستخدام تدوين الاستيعاب.

{} ، وحدد المفتاح والقيمة في جزء التعبير كمفتاح: القيمة.

{Key: Value for Any Variable Name in Iterable Object}

يمكن تحديد أي تعبير للمفتاح والقيمة.

l = ['Alice', 'Bob', 'Charlie']

d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}

لإنشاء قاموس جديد من قائمة مفاتيح وقيم ، استخدم وظيفة zip ().

keys = ['k1', 'k2', 'k3']
values = [1, 2, 3]

d = {k: v for k, v in zip(keys, values)}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}

نوع المولد(Generator expressions)

إذا تم استخدام الأقواس المربعة [] في قائمة تدوين الإدراك كأقواس دائرية () ، يتم إرجاع المولد بدلاً من المجموعة. وهذا ما يسمى تعبيرات المولد.

مثال على تدوين قائمة الفهم.

l = [i**2 for i in range(5)]

print(l)
# [0, 1, 4, 9, 16]

print(type(l))
# <class 'list'>

مثال على تعبير المولد. إذا قمت بطباعة () المولد كما هو ، فلن يطبع محتوياته ، ولكن إذا قمت بتشغيله باستخدام عبارة for ، فيمكنك الحصول على المحتويات.

g = (i**2 for i in range(5))

print(g)
# <generator object <genexpr> at 0x10af944f8>

print(type(g))
# <class 'generator'>

for i in g:
    print(i)
# 0
# 1
# 4
# 9
# 16

تسمح تعبيرات المولد أيضًا بالتفرع والتداخل الشرطي باستخدام تدوين if وكذلك قائمة الفهم.

g_cells = ((row, col) for row in range(0, 3)
           for col in range(0, 2) if col == row)

print(type(g_cells))
# <class 'generator'>

for i in g_cells:
    print(i)
# (0, 0)
# (1, 1)

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

إذا كان تعبير المولد هو الوسيطة الوحيدة للدالة ، فيمكن حذف الأقواس المستديرة ().

print(sum([i**2 for i in range(5)]))
# 30

print(sum((i**2 for i in range(5))))
# 30

print(sum(i**2 for i in range(5)))
# 30

بالنسبة لسرعة المعالجة ، غالبًا ما يكون تدوين القائمة أسرع من تدوين المولد عند معالجة جميع العناصر.

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

لا يوجد تدوين لفهم tuple ، ولكن إذا استخدمت تعبيرًا منشئًا كوسيطة لـ tuple () ، فيمكنك إنشاء مجموعة في طريقة الاستيعاب.

t = tuple(i**2 for i in range(5))

print(t)
# (0, 1, 4, 9, 16)

print(type(t))
# <class 'tuple'>