۹ نکته در مورد خلاصه لیست در پایتون — راهنمای کاربردی
امروزه شاهد هستیم که افراد زیادی شروع به یادگیری پایتون کردهاند و پایتون در حال تبدیل شدن به یکی از محبوبترین زبانهای برنامهنویسی در تقریباً همه حوزهها از توسعه وب، محاسبات علمی و به طور خاص هوش مصنوعی است. مهم نیست که میخواهید با پایتون چه کاری انجام دهید، در هر صورت ناگزیر هستید ساختمانهای داده پایتون، روش اعلان متغیر و تابع، گزارههای شرطی، گردش کنترل برنامه و دیگر مفاهیم مقدماتی را بیاموزید. یکی از مهمترین خصوصیات ویژه پایتون که ممکن است افراد مبتدی زیادی را سردرگم سازد مفهوم «خلاصه لیست» (list comprehension) است که روشی اجمالی برای ایجاد لیستها محسوب میشود. در این مقاله برخی نکات مقدماتی را برای کسب مهارت در مورد خلاصه لیست در پایتون معرفی خواهیم کرد.
ساختار ابتدایی خلاصه لیست در پایتون
ابتداییترین شکل خلاصه لیست در پایتون دارای ساختار زیر است. چنان که پیشتر اشاره کردیم، خلاصه لیست در پایتون به منظور ارائه روشی منسجم برای انجام کارهای خاص مانند ایجاد لیست عرضه شده است. شکل بسط یافته به طور معمول به صورت یک حلقه for بیان میشود که در آن هر آیتم عنصر تکرارپذیر (iterable) عملیات خاصی را چنان که در عبارت مشخص شده است اجرا میکند.
1# list comprehension
2[expression for item in iterable]
3# expanded form
4for item in iterable:
5 expression
ایجاد یک لیست
جای شگفتی نیست که همه کاربردهای رایج خلاصه لیست در ایجاد منسجم یک لیست خلاصه شده است.
فرض کنید که با خلاصهسازی لیست آشنا نباشیم، در این صورت احتمالاً برای ساخت یک خلاصه لیست در پایتون باید کاری مانند زیر انجام بدهیم. به این منظور ابتدا یک لیست خالی را اعلان میکنیم و سپس در یک حلقه for تکتک آیتمها را به لیست الحاق میکنیم.
1>>> pets = ('bird', 'snake', 'dog', 'turtle', 'cat', 'hamster')
2>>> uppercased_pets = []
3>>> for pet in pets:
4... uppercased_pets.append(pet.upper())
5...
6>>> uppercased_pets
7['BIRD', 'SNAKE', 'DOG', 'TURTLE', 'CAT', 'HAMSTER']
چنان که در بخش ساختار ابتدایی اشاره کردیم، گزاره حلقه for را میتوان در یک خط فشرده کرد. بدین ترتیب از خلاصه لیست تنها در یک خط استفاده کنیم و با روشی ساده یک لیست را با تکرار روی لیست اصلی ایجاد کنیم.
>>> pets = ('bird', 'snake', 'dog', 'turtle', 'cat', 'hamster') >>> uppercased_pets = [pet.upper() for pet in pets] >>> uppercased_pets ['BIRD', 'SNAKE', 'DOG', 'TURTLE', 'CAT', 'HAMSTER']
گزاره شرطی برای فیلتر کردن
برخی اوقات زمانی که از خلاصه لیست برای ایجاد لیست استفاده میکنیم، نمیخواهیم همه آیتمهای لیست موجود را در آن قرار دهیم. در این حالت، باید یک گزاره شرطی برای فیلتر کردن آیتمها در لیست موجود داشته باشیم. خلاصه لیست چنین ساختاری را در اختیار ما قرار میدهد.
1# list comprehension with a conditional statement
2[expression for item in iterable if some_condition]
3# expanded form
4for item in iterable:
5 if some_condition:
6 expression
نمونهای از کاربرد آن به صورت زیر است:
>>> primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] >>> squared_primes = [x*x for x in primes if x%10 == 3] >>> squared_primes [9, 169, 529]
اگر ارزیابی پیچیدهتری از شرط داشته باشیم، میتوانیم حتی از یک تابع نیز استفاده کنیم:
1>>> def has_four_legs(pet):
2... return pet in ('pig', 'dog', 'turtle', 'hamster', 'cat')
3...
4>>> pets = ('bird', 'snake', 'dog', 'turtle', 'cat', 'hamster')
5>>> four_legs_pets = [pet.capitalize() for pet in pets if has_four_legs(pet)]
6>>> four_legs_pets
7['Dog', 'Turtle', 'Cat', 'Hamster']
انتساب شرطی
برخی اوقات، نمیخواهیم آیتمها را از لیست اصلی فیلتر کنیم؛ بلکه میخواهیم شرط را ارزیابی کنیم تا مشخص شود که کدام عبارت استفاده شده است. ساختار و کاربرد این حالت در ادامه ارائه شده است. ساختار آن نیز در ادامه توضیح داده شده است:
1# basic syntax
2[expression0 if some_condition else expression1 for item in iterable]
3# syntax explained: compared to the list comprehension's basic syntax: [expression for item in iterable], we can thin about that (expression0 if some_condition else expression1) is a whole part that constitutes the expression in the general format
4>>> max_value = 10
5>>> numbers = (7, 9, 11, 4, 3, 2, 12)
6>>> ceiling_numbers0 = [number if number <= max_value else max_value for number in numbers]
7>>> ceiling_numbers0
8[7, 9, 10, 4, 3, 2, 10]
9>>> ceiling_numbers1 = [(number if number <= max_value else max_value) for number in numbers]
10>>> ceiling_numbers1
11[7, 9, 10, 4, 3, 2, 10]
جایگزینی ()map
در برخی موارد میبینیم که برخی افراد از ()map برای ایجاد لیست استفاده میکنند. تابع ()map به طور خاص دارای ساختار مانند زیر است و نمونهای از کاربرد ابتدایی آن نیز ارائه شده است. نکتهای که باید توجه داشته باشیم این است که تابع یک شیء iterable بازگشت میدهد و از این رو میتوانیم از تابع ()list برای تولید یک لیست از روی iterable استفاده کنیم.
1# map() returns an iterator object
2map(function, iterable)
3>>> pets = ('bird', 'snake', 'dog', 'turtle', 'cat', 'hamster')
4>>> uppercased_pets = list(map(str.upper, pets))
5>>> uppercased_pets
6['BIRD', 'SNAKE', 'DOG', 'TURTLE', 'CAT', 'HAMSTER']
چنان که پیشتر نشان دادیم، میتوانیم تابع ()map را با خلاصه لیست جایگزین کنیم.
1>>> pets = ('bird', 'snake', 'dog', 'turtle', 'cat', 'hamster')
2>>> uppercased_pets = [pet.upper() for pet in pets]
3>>> uppercased_pets
4['BIRD', 'SNAKE', 'DOG', 'TURTLE', 'CAT', 'HAMSTER']
خلاصه لیستهای تودرتو
فرض کنید یک چندتایی (tuple) مانند آن که در قطعه کد زیر میبینید داریم و میخواهیم یک لیست جدید از آیتمها بسازیم که برابر با مربع همه اعداد داخل چندتایی باشد. در این حالت، میتوانیم از خلاصه لیست تودرتو استفاده کنیم که ساختار آن در ادامه دیده میشود:
1# basic syntax of the nested list comprehensions
2[expression for sublist in outer_list for item in sublist]
3# expanded form
4for sublist in outer_list:
5 for item in sublist:
6 expression
7>>> nested_numbers = ((1, 4, 7, 8), (2, 3, 5))
8>>> squares = [x*x for numbers in nested_numbers for x in numbers]
9>>> squares
10[1, 16, 49, 64, 4, 9, 25]
با این که از نظر فنی میتوان چندین سطح مختلف برای خلاصه لیست تودرتو داشت، اما به منظور ارتقای خوانایی بهتر است از بیش از دو سطح استفاده نکنید.
استفاده از عملگر Walrus
یکی از قابلیتهای جدید در پایتون 3.8 معرفی عملگر Walrus (=:) بوده است که در عبارتهای انتساب استفاده میشود. فرض کنید میخواهیم ده بار از یک لیست حروف آیتمها را بداریم و لیستی که ایجاد میکنیم تنها شامل حروف صدادار از میان آیتمها خواهد بود. برای استفاده از عملگر Walrus به همراه خلاصه لیست به صورت زیر عمل میکنیم.
به طور خاص در مثال زیر بررسی میکنیم آیا یک حرف تصادفی که از میان حروف انتخاب شده، صدادار است یا نه و در صورتی که چنین باشد، آن را به حرف انتساب میدهیم تا عبارت خلاصه لیست در پایتون بتواند به آن دسترسی داشته باشد.
1>>> letters = list('this is to produce a list of letters')
2>>> letters
3['t', 'h', 'i', 's', ' ', 'i', 's', ' ', 't', 'o', ' ', 'p', 'r', 'o', 'd', 'u', 'c', 'e', ' ', 'a', ' ', 'l', 'i', 's', 't', ' ', 'o', 'f', ' ', 'l', 'e', 't', 't', 'e', 'r', 's']
4>>> import random
5>>> vowels = [letter.upper() for _ in range(0, 10) if (letter := random.choice(letters)) in list('aeoui')]
6>>> vowels
7['I', 'O', 'O', 'O', 'O']
خلاصه مجموعه
با این که اغلب افراد با قابلیت خلاصه لیست آشنا هستند، اما شاید ندانند که میتوان از «خلاصه مجموعه» (Set Comprehension) نیز استفاده کرد. ساختار ابتدایی و کاربرد آن به صورت زیر است. یک تفاوت اصلی در این است که به جای براکت ([]) از آکولاد ({}) استفاده میکنیم. عناصر مجموعه برحسب تعریف نمیتوانند تکراری باشند و این وضعیت با لیست متفاوت است، چون در آن امکان وجود عناصر تکراری وجود دارد. توجه داشته باشید که ما از یک گزاره شرطی روی یک خلاصه مجموعه نیز میتوان استفاده کرد.
1# syntax for set comprehension
2{expression for item in iterable}
3>>> numbers = (1, 34, 5, 8, 10, 12, 3, 90, 70, 70, 90)
4>>> unique_even_numbers = {number for number in numbers if number%2 == 0}
5>>> unique_even_numbers
6{34, 70, 8, 10, 12, 90}
خلاصه دیکشنری
اینک که با خلاصه لیست و خلاصه مجموعه آشنا شدید، بهتر است بدانید که ما «خلاصه دیکشنری» (Dict Comprehension) نیز داریم. ساختار ابتدایی و کاربرد آن در قطعه کد زیر نمایش یافته است:
1# syntax for dict comprehension
2{key_expression : value_expression for item in iterable}
3>>> words = ('python', 'is', 'a', 'big', 'snake')
4>>> len_words = {word : len(word) for word in words}
5>>> len_words
6{'python': 6, 'is': 2, 'a': 1, 'big': 3, 'snake': 5}
7>>> len_words_p = {word : len(word) for word in words if word.startswith('p')}
8>>> len_words_p
9{'python': 6}
سخن پایانی
در این مقاله به بررسی ساختار ابتدایی خلاصه لیست در پایتون و کاربردشان در موقعیتهای مختلف پرداختیم. علاوه بر خلاصه لیست در مورد خلاصه مجموعه و خلاصه دیکشنری نیز صحبت کردیم. این خلاصهها به ما امکان میدهند که انواع مختلفی از کلکسیونهای دادهای را به روش سادهای در پایتون با خوانایی بالا تولید کنیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی پایتون Python
- مجموعه آموزشهای برنامهنویسی
- آموزش پایتون (Python) | برنامه نویسی پایتون مقدماتی
- نصب پایتون — از صفر تا صد
- زبان برنامه نویسی پایتون (Python) — از صفر تا صد
==