مقدمه

اغلب لیست‌هایی که تا اینجا دیدیم، لیست‌های رشته‌ای بودند؛ یعنی لیست‌هایی که آیتم‌های آنها از نوع str هستند. لیست‌های رشته‌ای کاربرد زیادی دارند و در برنامه‌های خود به‌دفعات به آنها نیاز پیدا خواهیم کرد. اما در این درس قصد داریم به لیست‌های عددی بپردازیم که مثل لیست‌های رشته‌ای بسیار پرکاربرد هستند. در یک بازی برای کارهایی مانند دنبال کردن موقعیت مکانی کاراکترها یا ذخیره‌ی امتیاز کاربر و در اپ‌های data visualization برای نگهداری اعدادی که نشانگر دمای هوا، جمعیت، فاصله، طول و عرض جغرافیایی و غیره هستند، به لیست‌های عددی نیاز پیدا می‌کنیم.

استفاده از تابع range

تابع range() در پایتون به ما امکان می‌دهد که به سادگی یک مجموعه از اعداد را ایجاد کنیم. در کد زیر از این تابع برای تولید چند عدد و سپس چاپ آنها استفاده شده است.

Copy Icon numeric_lists.py
for value in range(1, 5): 
  print(value)

مثال بالا نشان می‌دهد که خروجی تابع range() یک کالکشن یا دنباله از اعداد است. بر خلاف آنچه که شاید در نگاه اول به نظر برسد، تابع range() در مثال بالا نه اعداد 1 تا 5 بلکه اعداد 1 تا 4 را تولید می‌کند. بنابراین، تابع range(a, b) اعداد a تا b-1 را تولید می‌کند یا به عبارت دیگر، ابتدای بازه بسته و انتهای آن باز است: چیزی که در ریاضیات به صورت [a, b) نمایش داده می‌شود.

1
2
3
4
          

می‌توانیم فقط یک آرگومان به تابع range() بدهیم که در این صورت، range(a) باعث تولید اعداد صفر تا a-1 می‌شود. مثلاً range(5) اعداد صفر تا 4 را تولید می‌کند.

تولید لیست‌های عددی با تابع range

همانطور که دیدیم، تابع range() یک سری یا مجموعه از اعداد را تولید می‌کند. اگر بخواهیم این مجموعه را به یک لیست تبدیل کنیم، کافیست تابع range() را به عنوان آرگومان به تابعی به نام list() بدهیم. برای روشن شدن موضوع، به مثال زیر دقت کنید.

Copy Icon numeric_lists.py
numbers = list(range(1, 6)) 
print(numbers)

نتیجه‌ی اجرای این کد به صورت زیر خواهد بود.

[1, 2, 3, 4, 5]
          

تابع range() می‌تواند یک آرگومان سوم هم داشته باشد که تعیین‌کننده‌ی سایز گام (step size) برای تولید عدد در بازه‌ی مشخص‌شده است.

Copy Icon numberic_lists.py
even_numbers = list(range(2, 11, 2)) 
print(even_numbers)

در اینجا سایز گام برابر با 2 است و بنابراین، اعداد زوج بازه‌ی 2 تا 10 تولید می‌شوند و چون تابع range() به عنوان آرگومان به تابع list() داده شده، اعداد تولید شده به یک لیست تبدیل می‌شوند.

[2, 4, 6, 8, 10]

تقریباً هر مجموعه‌ای از اعداد را می‌توان با استفاده از تابع range() ایجاد کرد. فرض کنید بخواهیم یک لیست عددی متشکل از مجذور (توان دوم) اعداد 1 تا 10 بسازیم.

Copy Icon numeric_lists.py
squares = [] 
for value in range(1, 11): 
  square = value ** 2 
  squares.append(square) 
print(squares)

در این مثال، ابتدا یک لیست خالی تعریف شده و سپس، هر یک از اعداد بازه‌ی 1 تا 10 به توان 2 رسیده و به لیست اضافه شده است. یادآوری می‌کنم که در پایتون نماد ** برای عمل توان به کار می‌رود.

کد قبل را می‌توانیم با حذف متغیر square به شکل خلاصه‌تری بنویسیم.

Copy Icon numeric_lists.py
squares = [] 
for value in range(1, 11): 
  squares.append(value**2) 
print(squares)

نتیجه‌ی این کد با کد قبل یکی است و می‌توانیم از هر دو روش استفاده کنیم. نمی‌توانیم حکم مطلقی راجع به برتری یکی از این دو روش به دیگری صادر کنیم. استفاده از متغیر حلقه (روش اول) گاهی اوقات باعث می‌شود برنامه خواناتر شود اما گاهی اوقات مزیتی ندارد و فقط برنامه را طولانی‌تر می‌کند. به طور کلی، بهتر است ابتدا تمرکز خود را روی نوشتن کدی که درک آن راحت‌تر است، بگذاریم و سپس، به بهبودهای ممکن فکر کنیم.

چند تابع آماری برای لیست‌های عددی

در این بخش با چند تابع آماری آشنا می‌شویم که هنگام کار با لیست‌های عددی مفید واقع می‌شوند. توابع min() و max() برای پیدا کردن کوچکترین و بزرگترین عدد در یک لیست و تابع sum() برای محاسبه‌ی مجموع اعداد یک لیست کاربرد دارند.

>>> digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] 
>>> min(digits) 
0 
>>> max(digits) 
9 
>>> sum(digits) 
45
          

ساخت لیست با تکنیک List Comprehension

در پایتون List Comprehension یک روش فشرده و محتصر برای ساخت لیست از روی کالکشن‌های موجود است. این روش نه تنها کد ما را کوتاه‌تر و خواناتر می‌کند، بلکه به دلیل استفاده‌ی مستقیم از عبارات در داخل لیست، اغلب سرعت اجرای کد را هم افزایش می‌دهد. ساختار کلی List Comprehension در پایتون به صورت زیر است.

[expression for item in iterable if condition]

در این ساختار، expression عبارتی است که می‌خواهیم روی هر آیتم کالکشن اعمال شود، item عنصر یا آیتمی است که در هر تکرار انتخاب می‌شود، iterable کالکشن یا دنباله‌ای است که می‌خواهیم روی آن پیمایش کنیم و condition که یک بخش اختیاری است، شرطی است که هر آیتمی که داشته باشد، وارد لیست جدید می‌شود.

به عنوان یک مثال ساده، فرش کنید می‌خواهیم لیستی از اعداد صفر تا 9 ایجاد کنیم.

Copy Icon numeric_lists.py
numbers = [x for x in range(10)]
print(numbers)

حالا فرض کنید می‌خواهیم فقط اعداد زوج بین صفر تا 9 را در لیست جدید داشته باشیم.

Copy Icon numeric_lists.py
even_numbers = [x for x in range(10) if x % 2 == 0]
print(even_numbers)

اگر این کد را اجرا کنیم، نتیجه‌ی زیر را دریافت خواهیم کرد.

[0, 2, 4, 6, 8]

این امکان هم وجود دارد که آیتم‌ها را قبل از افزودن به لیست جدید، تغییر دهیم. برای مثال، در کد زیر مجذور اعداد 0 تا 9 را در یک لیست قرار داده‌ایم.

Copy Icon numeric_lists.py
squares = [x ** 2 for x in range(10)]
print(squares)            
          

خروجی کد بالا به صورت زیر خواهد بود.

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]