From fbe8e836da5481d21d55ef6bae0f9f524018de07 Mon Sep 17 00:00:00 2001 From: Saeid Date: Sat, 15 Apr 2023 10:46:57 +0430 Subject: [PATCH 1/5] split l08 --- source/index.rst | 3 +- ...8.rst => l08-list-and-tuple-in-python.rst} | 855 +---------------- source/lessons/l08-set-and-dict-in-python.rst | 878 ++++++++++++++++++ 3 files changed, 890 insertions(+), 846 deletions(-) rename source/lessons/{l08.rst => l08-list-and-tuple-in-python.rst} (51%) create mode 100644 source/lessons/l08-set-and-dict-in-python.rst diff --git a/source/index.rst b/source/index.rst index 0150311..94beadf 100644 --- a/source/index.rst +++ b/source/index.rst @@ -36,7 +36,8 @@ lessons/l06-python-syntax lessons/l07-numeric-types-in-python lessons/l07-string-in-python - lessons/l08 + lessons/l08-list-and-tuple-in-python + lessons/l08-set-and-dict-in-python lessons/l09 lessons/l10 lessons/l11 diff --git a/source/lessons/l08.rst b/source/lessons/l08-list-and-tuple-in-python.rst similarity index 51% rename from source/lessons/l08.rst rename to source/lessons/l08-list-and-tuple-in-python.rst index 60b80f5..c19806a 100644 --- a/source/lessons/l08.rst +++ b/source/lessons/l08-list-and-tuple-in-python.rst @@ -1,24 +1,28 @@ .. role:: emoji-size .. meta:: - :description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش انواع داده در پایتون، آموزش انواع لیست (list)، تاپل (tuple)، دیکشنری (dict) در پایتون، دسته بندی انواع داده در پایتون - :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, انواع شی در پایتون, انواع داده در پایتون, پایتون + :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان داده در پایتون، list و tuple + :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان داده در پایتون, list در پایتون, tuple در پایتون -درس ۰۸: انواع داده یا شی در پایتون: set ،dict ،tuple ،list و None +.. _lesson-08.1: + +درس ۰۸: ساختمان داده در پایتون: list و tuple ==================================================================================== .. figure:: /_static/pages/08-python-built-in-data-types-2.jpg :align: center - :alt: انواع داده یا شی در پایتون: set ،dict ،tuple، list و None + :alt: درس ۰۸: ساختمان داده در پایتون: tuple و list :class: page-image Photo by `Natalia Y `__ + +از درس هفتم با انواع داده از پیش آماده در پایتون آشنا شده‌ایم و در این درس به ساختمان‌های داده در پایتون خواهیم پرداخت. ساختمان‌های داده یا Data Structures به اشیایی گفته می‌شود که برای نگهداری از یک مجموعه داده طراحی شده‌اند و هر یک دارای ویژگی منحصربه‌فرد خود است. برای مثال قابل تغییر بودن، امکان حفظ ترتیب اعضا، امکان نگهداری داده‌های تکراری یا تنها اجبار به نگهداری داده‌های یکتا که هر یک مناسب وضعیت خاصی در برنامه‌نویسی هستند. این درس به بررسی چهار ساختمان داده متداول در پایتون خواهد پرداخت: لیست (list)، تاپِل (tuple)، مجموعه (set) و دیکشنری (dict) -پایتون هر «نوع داده» (Data Type) را توسط یک کلاس ارایه می‌دهد؛ بنابراین هر داده یک نمونه یا یک شی از کلاسی مشخص است. هر چند برنامه‌نویس نیز می‌تواند با تعریف کلاس، نوع دلخواه خود را داشته باشد ولی در این درس می‌خواهیم درباره آن بخشی از انواع داده یا انواع شی‌ (Object Types) که به شکل آماده (Built-in) در اختیار مفسر زبان پایتون قرار داده شده است صحبت کنیم. -این درس در ادامه درس پیش به بررسی برخی از انواع دیگر پایتون به مانند «لیست»، «تاپل»، «دیکشنری» و «مجموعه» می‌پردازد. +به منظور جلوگیری از طولانی شدن متن درس و همینطور سادگی در مطالعه، محتوا این درس در قالب دو بخش ارایه می‌شود که بخش نخست تنها به شرح لیست (list) و تاپِل (tuple) خواهد پرداخت. + @@ -1036,850 +1040,11 @@ >>> type(t) - -دیکشنری ---------- - -یکی دیگر از انواع انعطاف پذیر آماده در پایتون «**دیکشنری**» (Dictionary) می‌باشد که با نام کوتاه شده ``dict`` ارایه شده است. اشیا نوع دیکشنری با استفاده از نماد آکولاد ``{ }`` معرفی‌ می‌شوند و هر داده در آن به شکل یک جفت «**کلید:مقدار**» (key:value) ذخیره می‌گردد. از این نوع شی با عنوان شی mapping (نگاشت) پایتون نیز یاد می‌شود چرا که در این نوع هر شی «کلید» به یک شی «مقدار» map یا نگاشت داده می‌شود. شی دیکشنری دنباله نیست ولی تغییر پذیر بوده و «مقدار» هر عضو توسط «کلید» متناظر با آن دستیابی می‌شود. شی «مقدار» می‌تواند از هر نوعی باشد حتی یک شی دیکشنری دیگر ولی شی «کلید» تنها می‌بایست از انواع «تغییر ناپذیر» انتخاب شود و باید توجه داشت که تمام «کلید»‌های یک شی دیکشنری می‌بایست «**یکتا**» (Unique) باشند. - -:: - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> type(d) - - - >>> d - {1: 'One', 2: 'Two', 3: 'Three'} - - >>> print(d) - {1: 'One', 2: 'Two', 3: 'Three'} - - >>> import sys - >>> sys.getsizeof(d) - 288 - -در نمونه کد بالا؛ اشیا ``1``، ``2`` و ``3`` کلید‌های شی ``d`` هستند که به ترتیب با اشیای ``'One'`` و ``'Two'`` و ``'Three'`` نگاشت شده‌اند. برای دستیابی هر مقدار شی دیکشنری ``dic`` از الگو ``[dic[key`` استفاده می‌کنیم که ``key`` در آن، کلید متصل به مقدار مورد نظر می‌باشد:: - - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d[0] - Traceback (most recent call last): - File "", line 1, in - KeyError: 0 - - >>> d[1] - 'One' - - >>> d[3][2:] - 'ree' - - -``[d[3`` اشاره به مقدار ``'Three'`` دارد؛ و از آنجا که این شی یک دنباله است می‌توان به روش دنباله‌ها (یعنی با استفاده از اندیس موقعیت) عضوهای این شی را نیز دستیابی نماییم. - - -به چند مثال دیگر توجه نمایید:: - - >>> d = {} # An empty dictionary - >>> d - {} - -:: - - >>> d = {'name': 'Bob', 'age': 40} - - >>> d['name'] - 'Bob' - >>> d['age'] - 40 - -:: - - >>> d = {'cb4f2': {'name': 'Bob', 'age': 40}} - - >>> d['cb4f2']['age'] - 40 - - - -ساختار نوع دیکشنری مشابه «جدول درهم‌سازی» (`Hash table `_) است و کاربرد‌های فراوانی در الگوریتم‌های جستجو دارد. از این نوع همچنین می‌توان برای سازماندهی و ذخیره داده‌ها بر روی فایل استفاده کرد؛ برای نمونه فرض کنید می‌خواهیم چند فیلم با بازی Benedict Cumberbatch را به گونه‌ای در اختیار داشته باشیم که بتوانیم آن‌ها را بر اساس سال ساخت دستیابی نماییم:: - - >>> benedict_cumberbatch = {'2014':'The Imitation Game', - ... '2013':('The Fifth Estate', '12 Years a Slave', 'Star Trek Into Darkness'), - ... '2012':'The Hobbit: An Unexpected Journey', - ... '2011':('War Horse', ' Wreckers', 'Tinker Tailor Soldier Spy')} - >>> - - >>> benedict_cumberbatch['2014'] - 'The Imitation Game' - - >>> len(benedict_cumberbatch['2011']) - 3 - - >>> benedict_cumberbatch['2011'][0] - 'War Horse' - - -از تابع ``()len`` نیز می‌توان برای به دست آوردن تعداد عضوهای شی دیکشنری (جفتِ کلید:مقدار) استفاده کرد:: - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> len(d) - 3 - -با انتساب یک مقدار جدید به یک کلید موجود از شی دیکشنری می‌توان مقدار آن کلید را تغییر داد و با انتساب یک مقدار به یک کلید جدید که در شی دیکشنری وجود ندارد یک عضو جدید به آن شی افزوده می‌شود:: - - >>> d = {'name': 'Bob', 'age': 40} - - >>> d['name'] = 'Jhon' - >>> d - {'name': 'Jhon', 'age': 40} - - >>> d['job'] = 'unemployed' - >>> d - {'name': 'Jhon', 'job': 'unemployed', 'age': 40} - -*برخلاف شی لیست یا تاپل (یا در کل دنباله‌ها) که داده‌هایی منظم (Ordered) هستند و ترتیب یا جایگاه قرار گرفتن عضوهای آن‌ها اهمیت دارد، یک شی دیکشنری این طور نیست و ترتیب عضوها در آن کاملا بی اهمیت است.* - -با استفاده از دستوری مشابه ``[del dic[key`` نیز می‌توان یک عضو شی دیکشنری را حذف کرد:: - - >>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40} - - >>> del d['job'] - >>> d - {'name': 'Jhon', 'age': 40} - - -امکانی برای تغییر کلیدها وجود ندارد مگر آنکه عضو مورد نظر را حذف کرده و یک عضو جدید (همان مقدار ولی با کلیدی جدید) اضافه نمایید:: - - >>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40} - - >>> d['occupation'] = d['job'] - >>> del d['job'] - - >>> d - {'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'} - -.. rubric:: عملگرها برای دیکشنری - -عملگرهای ``+`` و ``*`` برای اشیا دیکشنری تعریف **نشده‌اند**. - -از عملگرهای عضویت می‌توان برای بررسی وجود یک **کلید** در شی دیکشنری استفاده کرد:: - - >>> 'job' in {'name': 'Bob', 'age': 40} - False - - >>> 'job' not in {'name': 'Bob', 'age': 40} - True - -در مورد عملکرد عملگر برابری ``==`` و عملگرهای هویت (``is`` و ``is not``) صحبت شده است؛ این عملگرها برای اشیا دیکشنری نیز کاربرد دارند. - - -.. rubric:: کپی کردن - -همانطور که گفته شد شی دیکشنری از انواع «تغییر پذیر» پایتون است و همان توضیحاتی که در مورد شی لیست بیان شد؛ در اینجا هم درست است و گاهی نیاز می‌شود که از ماژول ``copy`` برای کپی اشیا دیکشنری استفاده نماییم: - -* بدون کپی کردن:: - - >>> d1 = {'name': 'Bob', 'age': 40} - - >>> d2 = d1 - - >>> d1 == d2 - True - >>> d1 is d2 - True - - >>> d1['age'] = 46 - - >>> d1 - {'name': 'Bob', 'age': 46} - >>> d2 - {'name': 'Bob', 'age': 46} - - -* کپی سطحی:: - - >>> d1 = {'name': 'Bob', 'age': 40} - - >>> import copy - >>> d2 = copy.copy(d1) # shallow copy - - >>> d1 == d2 - True - >>> d1 is d2 # False! - False - - >>> d1['age'] = 46 - - >>> d1 - {'name': 'Bob', 'age': 46} - >>> d2 - {'name': 'Bob', 'age': 40} - - :: - - >>> d1 = {'names': ['Bob', 'Jhon'], 'ages': [40, 40]} - - >>> import copy - >>> d2 = copy.copy(d1) # shallow copy - - >>> d1 == d2 - True - >>> d1 is d2 # False! - False - - >>> d1['ages'][0] = 46 - - >>> d1 - {'ages': [46, 40], 'names': ['Bob', 'Jhon']} - - >>> # d2 has changed! - >>> d2 - {'ages': [46, 40], 'names': ['Bob', 'Jhon']} - -* کپی عمیق:: - - >>> d1 = {'names': ['Bob', 'Jhon'], 'ages': [40, 40]} - - >>> import copy - >>> d2 = copy.deepcopy(d1) # deep copy - - >>> d1 == d2 - True - >>> d1 is d2 # False! - False - - >>> d1['ages'][0] = 46 - - >>> d1 - {'ages': [46, 40], 'names': ['Bob', 'Jhon']} - >>> d2 - {'ages': [40, 40], 'names': ['Bob', 'Jhon']} - - -.. rubric:: تبدیل به شی دیکشنری - -برای تبدیل دیگر اشیا به نوع دیکشنری یا در کل ایجاد شی دیکشنری از کلاس ``()dict`` [`اسناد پایتون `__] استفاده می‌شود. توجه داشته باشید که عضوهای شی دیکشنری از طریق آرگومان‌ها و به شکل «**کلید=مقدار**» به کلاس فرستاده می‌شوند:: - - >>> d = dict(one=1, two=2, three=3) - - >>> d - {'two': 2, 'one': 1, 'three': 3} - >>> d['one'] - 1 - -*در این حالت برای انتخاب کلیدها باید قوانین انتخاب نام در پایتون را رعایت نماییم؛ برای مثال کلیدی که با عدد شروع شود مجاز نمی‌باشد.* - -برای فرستادن کلیدها و مقدارها می‌توانیم از تابع ``()zip`` [`اسناد پایتون `__] استفاده کنیم و خروجی این تابع را به عنوان آرگومان به کلاس ``dict`` ارسال کنیم. می‌توان اینگونه تصور کرد که این تابع تعدادی شی دنباله را می‌گیرد و عضوهای نظیر به نظیر آن‌ها را در کنار هم قرار می‌دهد؛ این دنباله‌ها باید تعداد عضو برابری داشته باشند؛ چرا که عضوهای اضافی هر دنباله نادیده گرفته می‌شود. خروجی ``()zip`` یک شی جدید از نوع ``zip`` است و برای مشاهده معمولا آن را به نوع لیست تبدیل می‌کنند:: - - >>> k = [1, 2, 3, 4, 5] - >>> v = ['x', 'y', 'z'] - - >>> z = zip(k, v) - - >>> z - - - >>> type(z) - - - >>> list(z) - [(1, 'x'), (2, 'y'), (3, 'z')] - -:: - - >>> k = (1, 2, 3) - >>> v = ('One', 'Two', 'Three') - - >>> d = dict(zip(k, v)) - - >>> d - {1: 'One', 2: 'Two', 3: 'Three'} - -در آینده باز هم از تابع ``()zip`` استفاده خواهیم کرد. - - - - -.. rubric:: برخی از متدهای کاربردی یک شی دیکشنری - -* ``()items`` [`اسناد پایتون `__] تمام عضوهای شی را برمی‌گرداند - ``()values`` [`اسناد پایتون `__] تمام مقدارهای موجود در شی را بر می‌گرداند - ``()keys`` [`اسناد پایتون `__] تمام کلیدهای موجود در شی را بر می‌گرداند:: - - >>> # Python 3.x - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.items() - dict_items([(1, 'One'), (2, 'Two'), (3, 'Three')]) - - >>> d.values() - dict_values(['One', 'Two', 'Three']) - - >>> d.keys() - dict_keys([1, 2, 3]) - - توجه داشته باشید که در نسخه‌های 3x پایتون خروجی این متدها از نوع متفاوتی است که با استفاده از ``()type`` می‌توانید مشاهده کنید؛ این نوع ``dict_view`` نامیده می‌شود [`اسناد پایتون 3x `__]. این متدها یک کپی از داده‌های مورد نظر (عضوها یا مقدارها یا کلیدها) را بر نمی‌گردانند بلکه می‌توان گفت پنجره‌ای برای مشاهده آنچه که هست باز می‌کنند و در هر زمان که این داده‌ها تغییر کنند این خروجی‌ها نیز تغییر می‌کنند. برای مشاهده بهتر این خروجی‌ها می‌توانید آن‌ها را به نوع لیست تبدیل نمایید:: - - >>> list(d.items()) - [(1, 'One'), (2, 'Two'), (3, 'Three')] - - >>> list(d.values()) - ['One', 'Two', 'Three'] - - >>> list(d.keys()) - [1, 2, 3] - - این متدها در پایتون 2x چنین خروجی ندارند و تنها یکی کپی از داده‌ها را برمی‌گردانند. البته در نسخه 2.7 متدهای معادلی با عنوان‌های ``()viewitems`` [`اسناد پایتون `__] و ``()viewvalues`` [`اسناد پایتون `__] و ``()viewkeys`` [`اسناد پایتون `__] پورت شده است:: - - >>> # Python 2.7 - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.viewitems() - dict_items([(1, 'One'), (2, 'Two'), (3, 'Three')]) - - >>> d.viewvalues() - dict_values(['One', 'Two', 'Three']) - - >>> d.viewkeys() - dict_keys([1, 2, 3]) - - :: - - >>> # Python 2.x - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.items() - [(1, 'One'), (2, 'Two'), (3, 'Three')] - - >>> d.values() - ['One', 'Two', 'Three'] - - >>> d.keys() - [1, 2, 3] - - - -* ``()clear`` [`اسناد پایتون `__] - تمام عضوهای یک شی دیکشنری را حذف می‌کند:: - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.clear() - >>> d - {} - -* ``()copy`` [`اسناد پایتون `__] - این متد یک کپی سطحی از شی برمی‌گرداند:: - - >>> d1 = {'name':'Bob'} - - >>> d2 = d1.copy() - - >>> d1 is d2 - False - -* ``(fromkeys(seq`` [`اسناد پایتون `__] - یک دنباله از کلیدها را دریافت و یک شی جدید دیکشنری با استفاده از آن‌ها ایجاد می‌کند؛ البته کلیدهای این شی فاقد مقدار هستند که می‌بایست در زمانی دیگر به آن‌ها مقدار داد:: - - >>> k = (1, 2, 3) # or k=[1, 2, 3] or k='123' - - >>> dict.fromkeys(k) - {1: None, 2: None, 3: None} - - - توجه داشته باشید که این متد توسط خود کلاس ``dict`` فراخوانی می‌شود. - - این متد یک آرگومان اختیاری نیز دارد که توسط آن می‌توان یک شی را به عنوان «مقدار» پیش‌فرض کلید‌ها تعیین نمود:: - - >>> k = (1, 2, 3) - - >>> dict.fromkeys(k, '-*-') - {1: '-*-', 2: '-*-', 3: '-*-'} - -* ``(pop(key`` [`اسناد پایتون `__] - عضو دارنده کلید ``key`` را حذف و مقدار آن را برمی‌گرداند. چنانچه عضوی با این کلید یافت نشود شی پیش‌فرض تعیین شده (آرگومان دوم که اختیاری است) را برمی‌گرداند و اگر این آرگومان ارسال نشده باشد یک خطا گزارش می‌دهد:: - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.pop(2) - 'Two' - >>> d - {1: 'One', 3: 'Three'} - - >>> d.pop(2) - Traceback (most recent call last): - File "", line 1, in - KeyError: 2 - - >>> d.pop(2, 'Oops!') - 'Oops!' - - - از این متد می‌توان برای تغییر راحت‌تر کلیدها استفاده کرد!:: - - >>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40} - - >>> d['occupation'] = d.pop('job') - - >>> d - {'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'} - - متد مشابه دیگری نیز با نام ``()popitem`` [`اسناد پایتون `__] - که بدون آرگومان است - در دسترس می‌باشد؛ این متد در هر فراخوانی یک عضو از شی مورد نظر را به صورت دلخواه حذف و به شکل تاپل (key, value) برمی‌گرداند و چنانچه دیکشنری خالی باشد یک خطا ``KeyError`` گزارش می‌دهد:: - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.popitem() - (1, 'One') - -* ``(get(key`` [`اسناد پایتون `__] - مقدار مربوط به کلید ``key`` را برمی‌گرداند. چنانچه درون شی مورد نظر هیچ عضوی با این کلید وجود نداشته باشد شی پیش‌فرض تعیین شده (آرگومان دوم که اختیاری است) را برمی‌گرداند و اگر این آرگومان ارسال نشده باشد هیچ خطایی گزارش **نمی‌دهد**:: - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.get(1) - 'One' - - >>> d.get(0) - >>> - - >>> d.get(0, False) - False - - -* ``(setdefault(key`` [`اسناد پایتون `__] - مقدار مربوط به کلید ``key`` را برمی‌گرداند. چنانچه عضوی با این کلید درون شی مورد نظر وجود نداشته باشد، کلید را به همراه مقدار پیش‌فرض تعیین شده (آرگومان دوم که اختیاری است) درون شی اضافه می‌کند و خود این مقدار را برمی‌گرداند؛ اگر آرگومان دوم ارسال نشده باشد به صورت پیش‌فرض مقدار ``None`` در نظر گرفته خواهد شد:: - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.setdefault(1) - 'One' - >>> d - {1: 'One', 2: 'Two', 3: 'Three'} - - >>> d.setdefault(5) - >>> d - {1: 'One', 2: 'Two', 3: 'Three', 5: None} - - >>> d.setdefault(7, 'Seven') - 'Seven' - >>> d - {1: 'One', 2: 'Two', 3: 'Three', 5: None, 7: 'Seven'} - - - -* ``()update`` [`اسناد پایتون `__] - یک شی دیکشنری دیگر را به عنوان آرگومان می‌گیرد و عضوهای شی مورد نظر را بر اساس آن تغییر می‌دهد:: - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d2 = {5:'Five', 6:'Six'} - >>> d.update(d2) - >>> d - {1: 'One', 2: 'Two', 3: 'Three', 5: 'Five', 6: 'Six'} - - >>> d3 = {1:'0001'} - >>> d.update(d3) - >>> d - {1: '0001', 2: 'Two', 3: 'Three', 5: 'Five', 6: 'Six'} - - - -مجموعه --------- - -«**مجموعه**» (Set) از انواع «نامنظم» (Unordered) و «تغییر پذیر» (Mutable) پایتون است که معادل مفهوم مجموعه در ریاضیات می‌باشد. **هر عضو مجموعه می‌بایست یکتا و یکی از انواع «تغییر ناپذیر» باشد**. نوع مجموعه یا ``set`` در نسخه‌ 3x با کمی تفاوت ارایه شده است. در نسخه‌های 2x تنها می‌توان با استفاده از کلاس ``()set`` [`اسناد پایتون `__] اقدام به ایجاد این اشیا نمود در حالی که در پایتون 3x این کار به سادگی و تنها با استفاده از نماد آکولاد ``{ }`` نیز امکان پذیر شده است؛ (البته این ویژگی به نسخه 2.7 هم پورت شده است). در دو نمونه کد پایین به چگونگی تعریف و نمایش شی مجموعه توجه نمایید: - -*نسخه‌های 2x:* - -:: - - >>> L = [1, 2, 3, 4, 5] - - >>> s = set(L) - - >>> type(s) - - - >>> s - set([1, 2, 3, 4, 5]) - - >>> print s - set([1, 2, 3, 4, 5]) - -:: - - >>> s = {1, 2, 3, 4, 5} # Python 2.7 - - >>> type(s) - - - >>> s - set([1, 2, 3, 4, 5]) - - -*نسخه‌های 3x:* - -:: - - >>> L = [1, 2, 3, 4, 5] - - >>> s = set(L) - - >>> type(s) - - - >>> s - {1, 2, 3, 4, 5} - - >>> print(s) - {1, 2, 3, 4, 5} - -:: - - >>> s = {1, 2, 3, 4, 5} - - >>> type(s) - - - >>> s - {1, 2, 3, 4, 5} - -هیچ سینتکس خاصی برای ایجاد یا بیان یک شی خالی از نوع مجموعه وجود ندارد و تنها می‌بایست از کلاس ``()set`` - بدون آرگومان - استفاده کرد. توجه داشته باشید که ``{}`` بیانگر یک شی دیکشنری خالی است و نه یک مجموعه خالی:: - - >>> a = {} # Python 2.x - >>> type(a) - - - >>> b = set() - >>> type(b) - - - >>> b - set([]) - -:: - - >>> a = {} # Python 3.x - >>> type(a) - - - >>> b = set() - >>> type(b) - - - >>> b - set() - - -از تابع ``()len`` می‌توان برای به دست آوردن تعداد عضوهای یک شی مجموعه نیز استفاده کرد:: - - >>> s = {1, 2, 3, 4, 5} - >>> len(s) - 5 - - - -.. rubric:: عملگرها برای مجموعه - -تعدادی از عملگرها هستند که برای اشیا مجموعه تعریف خاصی پیدا می‌کنند؛ در حالی که در مورد اشیا دیگر چنین رفتاری ندارند. این عملگرها در واقع پیاده‌سازی تعریف مشخصی در مفهوم ریاضی مجموعه‌ها هستند: - -* ``|`` اجتماع (Union): مانند ``A | B`` که حاصل آن مجموعه‌ای می‌باشد که تمام عضوهای مجموعه ``A`` و مجموعه ``B`` را داشته باشد و هیچ عضو اضافه دیگری نداشته باشد. - - >>> A | B - {'w', 'y', 'q', 't', 'r', 'z', 's', 'v', 'u', 'x'} - -* ``&`` اشتراک (Intersection): مانند ``A & B`` که حاصل آن مجموعه‌ای می‌باشد که تنها شامل عضوهایی است که هم در مجموعه ``A`` هستند و هم در مجموعه ``B``:: - - >>> A & B - {'w', 'v', 'u'} - - -* ``-`` تفاضل (Difference): مانند ``A - B`` که حاصل آن مجموعه‌ای می‌باشد که تنها شامل عضوهایی از مجموعه ``A`` است كه در مجموعه ``B`` نيستند:: - - >>> A = {'u', 'v', 'w', 'x', 'y', 'z'} - >>> B = {'q', 'r', 's', 't', 'u', 'v', 'w',} - - >>> A - B - {'z', 'y', 'x'} - - -* ``^`` تفاضل متقارن (Symmetric difference): مانند ``A ^ B`` که حاصل آن مجموعه‌ای می‌باشد که برابر اجتماع ِ تفاضل ``A`` از ``B`` و تفاضل ``B`` از ``A`` می‌باشد یعنی: ``(A-B) | (B-A)``:: - - >>> A ^ B - {'q', 'y', 't', 'r', 'z', 's', 'x'} - - :: - - >>> (A-B) | (B-A) - {'y', 'q', 't', 'r', 'z', 'x', 's'} - - - تفاضل متقارن را می‌توان به صورت پایین نیز تعریف کرد:: - - >>> (A|B) - (B&A) - {'y', 'q', 't', 'r', 'z', 's', 'x'} - -* ``>`` زیرمجموعه (Subset): مانند ``A < B`` که اگر مجموعه ``A`` زیرمجموعه‌ای از مجموعه ``B`` باشد مقدار ``True`` را برمی‌گرداند. در مقابل عملگر ``<`` قرار دارد که برای مثال در عبارت ``A > B`` اگر مجموعه ``A`` یک Superset برای مجموعه ``B`` باشد مقدار ``True`` را برمی‌گرداند:: - - >>> A = {1, 2, 3, 4, 5} - >>> B = {1, 2, 3} - - >>> A < B - False - - >>> A > B - True - -برخی از عملگرهای عمومی نیز برای اشیا مجموعه قابل استفاده هستند:: - - >>> A = {'a', 'b', 'c'} - - >>> 'a' in A - True - >>> 'c' not in A - False - -:: - - >>> A = {1, 2, 3, 4, 5} - >>> B = {1, 2, 3} - - >>> A == B - False - - >>> C = A - - >>> A == C - True - - >>> A is C - True - -.. rubric:: برخی از متدهای کاربردی یک شی مجموعه - - -* ``()union`` [`اسناد پایتون `__] - تعدادی شی مجموعه را دریافت می‌کند و یک مجموعه جدید که برابر اجتماع شی مورد نظر با آن‌ها است را برمی‌گرداند:: - - >>> A = {'a', 'b', 'c'} - >>> B = {1, 2, 3} - - >>> {'t', 1, 'a'}.union(A, B) - {'a', 1, 2, 3, 't', 'b', 'c'} - - >>> {'t', 1, 'a'} | A | B - {1, 2, 3, 'b', 't', 'a', 'c'} - - به صورت مشابه می‌توان از متدهای ``()intersection`` [`اسناد پایتون `__] برای اشتراک، ``()difference`` [`اسناد پایتون `__] برای تفاضل، ``()symmetric_difference`` [`اسناد پایتون `__] - که تک آرگومانی است - برای تفاضل متقارن، ``()issubset`` [`اسناد پایتون `__] و ``()issuperset`` [`اسناد پایتون `__] - که هر دو تک آرگومانی هستند - برای بررسی زیرمجموعه یا Superset بودن استفاده کرد. - - - -* ``()clear`` [`اسناد پایتون `__] - تمام عضوهای یک شی مجموعه را حذف می‌کند:: - - >>> A = {'a', 'b', 'c'} - - >>> A.clear() - >>> A - set() - -* ``(add(x`` [`اسناد پایتون `__] - شی تغییر ناپذیر ``x`` را در صورتی که از قبل درون شی مجموعه مورد نظر وجود نداشته باشد به آن اضافه می‌کند:: - - >>> A = {'a', 'b', 'c'} - - >>> A.add(1) - >>> A - {'a', 'c', 1, 'b'} - -* ``(remove(x`` [`اسناد پایتون `__] - عضو ``x`` را از شی مجموعه مورد نظر حذف می‌کند. در صورتی که ``x`` درون مجموعه وجود نداشته باشد یک خطا گزارش می‌دهد:: - - >>> A = {'a', 'b', 'c', 1} - - >>> A.remove(1) - >>> A - {'c', 'a', 'b'} - - >>> A.remove(1) - Traceback (most recent call last): - File "", line 1, in - KeyError: 1 - - - متد مشابه دیگری نیز با الگو ``(discard(x`` [`اسناد پایتون `__] وجود دارد که این متد چنانچه ``x`` وجود داشته باشد آن را حذف می‌کند؛ بنابرین در صورت نبودن ``x`` خطایی گزارش نمی‌گردد:: - - >>> A = {'c', 'a', 'b'} - - >>> A.discard(1) - >>> A - {'b', 'a', 'c'} - - - -* ``()pop`` [`اسناد پایتون `__] - این متد آرگومانی ندارد و به صورت دلخواه یک عضو از مجموعه را حذف و به عنوان خروجی برمی‌گرداند. در مواردی که مجموعه خالی باشد یک خطا گزارش می گردد:: - - >>> A = {'a', 'b', 'c'} - - >>> A.pop() - 'a' - - :: - - >>> A.pop() - Traceback (most recent call last): - File "", line 1, in - KeyError: 'pop from an empty set' - - -.. rubric:: frozenset - -همانطور که پیش از این بیان شد مجموعه یک شی «تغییر پذیر» است با عضوهای «تغییر ناپذیر» و به دلیل همین تغییر پذیری است که می‌توانیم به سادگی توسط متدها عضوی به آن افزوده یا حذف نماییم. **”frozenset“** یک نوع جدید مجموعه است. همانگونه که می‌توانیم یک شی تاپل را معادل یک شی لیست تغییر ناپذیر تصویر کنیم؛ frozenset را نیز می‌توان **یک شی مجموعه تغییر ناپذیر** تصور کرد. نوع ``frozenset`` همان نوع ``set`` است، با تمام ویژگی‌های آن به غیر از تغییر پذیری که با استفاده از کلاس ``()frozenset`` ایجاد می‌گردد: - -*نسخه‌های 2x:* - -:: - - >>> L = [1, 2, 3] - - >>> A = frozenset(L) - - >>> type(A) - - - >>> A - frozenset([1, 2, 3]) - -*نسخه‌های 3x:* - -:: - - >>> L =[1, 2, 3] - - >>> A = frozenset(L) - - >>> type(A) - - - >>> A - frozenset({1, 2, 3}) - -با استفاده از تابع ``()dir`` می‌توان متوجه متدهای در دسترس شی ``frozenset`` شد:: - - >>> dir(frozenset) # Python 3.x - ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union'] - - -NoneType ----------- - -این نوع شی فاقد مقدار است و با انتساب ثابت ``None`` [`اسناد پایتون `__] به یک نام ایجاد می‌گردد:: - - >>> n = None - - >>> type(n) - - - >>> print(n) - None - - >>> import sys - >>> sys.getsizeof(a) - 16 - - >>> n = 5 - >>> type(n) - - -``None`` در پایتون 3x جزو کلمه‌های کلیدی (keywords) تعریف شده است. - - -دسته‌بندی ------------ - -در این بخش به دسته‌بندی انواع شی بر اساس برخی از تعریف‌های پایتون پرداخته شده است. - - -* انواع عددی (Numeric Types): - - .. code-block:: html - :linenos: - - - int - - long (2.x) - - float - - complex - - Decimal - - Fraction - - bool - -* انواع دنباله (Sequence Types): - - .. code-block:: html - :linenos: - - - str - - unicode (2.x) - - bytes (3.x) - - bytearray (3.x/2.6+) - - tuple - - list - -* انواع تغییر ناپذیر (Immutable Types): - - .. code-block:: html - :linenos: - - - int - - long (2.x) - - float - - complex - - Decimal - - Fraction - - bool - - str - - unicode (2.x) - - bytes (3.x) - - tuple - - frozenset - - -* انواع تغییر پذیر (Mutable Types): - - .. code-block:: html - :linenos: - - - bytearray (3.x/2.6+) - - list - - dict - - set - -* انواع نگاشت (Mapping Types): - - .. code-block:: html - :linenos: - - - dict - -* انواع مجموعه (Set Types): - - .. code-block:: html - :linenos: - - - set - - frozenset - - -* برخی دیگر: - - .. code-block:: html - :linenos: - - - zip - - dict_views - - NoneType - -*در درس‌های بعد نیز با انواع آماده (Built-in) دیگری آشنا خواهیم شد.* - | ---- :emoji-size:`😊` امیدوارم مفید بوده باشه -`لطفا دیدگاه و سوال‌های مرتبط با این درس خود را در کدرز مطرح نمایید. `_ diff --git a/source/lessons/l08-set-and-dict-in-python.rst b/source/lessons/l08-set-and-dict-in-python.rst new file mode 100644 index 0000000..dc4c139 --- /dev/null +++ b/source/lessons/l08-set-and-dict-in-python.rst @@ -0,0 +1,878 @@ +.. role:: emoji-size + +.. meta:: + :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان داده در پایتون، set و dict + :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان داده در پایتون, set در پایتون, dict در پایتون + + +درس ۰۸: ساختمان داده در پایتون: set و dict +==================================================================================== + +.. figure:: /_static/pages/08-python-built-in-data-types-2.jpg + :align: center + :alt: درس ۰۸: ساختمان داده در پایتون: set و dict + :class: page-image + + Photo by `Natalia Y `__ + + +از درس هفتم با انواع داده از پیش آماده در پایتون آشنا شده‌ایم و در این درس به ساختمان‌های داده در پایتون خواهیم پرداخت. ساختمان‌های داده یا Data Structures به اشیایی گفته می‌شود که برای نگهداری از یک مجموعه داده طراحی شده‌اند و هر یک دارای ویژگی منحصربه‌فرد خود است. برای مثال قابل تغییر بودن، امکان حفظ ترتیب اعضا، امکان نگهداری داده‌های تکراری یا تنها اجبار به نگهداری داده‌های یکتا که هر یک مناسب وضعیت خاصی در برنامه‌نویسی هستند. این درس به بررسی چهار ساختمان داده متداول در پایتون خواهد پرداخت: لیست (list)، تاپِل (tuple)، مجموعه (set) و دیکشنری (dict) + +این بخش در ادامه شرح «لیست» و «تاپل» به شرح دو نوع دیگر از ساختمان‌های داده در پایتون می‌پردازد: «مجموعه» و «دیکشنری» + + + +:emoji-size:`✔` سطح: مقدماتی + +---- + +.. contents:: سرفصل‌ها + :depth: 2 + +---- + + +دیکشنری +--------- + +یکی دیگر از انواع انعطاف پذیر آماده در پایتون «**دیکشنری**» (Dictionary) می‌باشد که با نام کوتاه شده ``dict`` ارایه شده است. اشیا نوع دیکشنری با استفاده از نماد آکولاد ``{ }`` معرفی‌ می‌شوند و هر داده در آن به شکل یک جفت «**کلید:مقدار**» (key:value) ذخیره می‌گردد. از این نوع شی با عنوان شی mapping (نگاشت) پایتون نیز یاد می‌شود چرا که در این نوع هر شی «کلید» به یک شی «مقدار» map یا نگاشت داده می‌شود. شی دیکشنری دنباله نیست ولی تغییر پذیر بوده و «مقدار» هر عضو توسط «کلید» متناظر با آن دستیابی می‌شود. شی «مقدار» می‌تواند از هر نوعی باشد حتی یک شی دیکشنری دیگر ولی شی «کلید» تنها می‌بایست از انواع «تغییر ناپذیر» انتخاب شود و باید توجه داشت که تمام «کلید»‌های یک شی دیکشنری می‌بایست «**یکتا**» (Unique) باشند. + +:: + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> type(d) + + + >>> d + {1: 'One', 2: 'Two', 3: 'Three'} + + >>> print(d) + {1: 'One', 2: 'Two', 3: 'Three'} + + >>> import sys + >>> sys.getsizeof(d) + 288 + +در نمونه کد بالا؛ اشیا ``1``، ``2`` و ``3`` کلید‌های شی ``d`` هستند که به ترتیب با اشیای ``'One'`` و ``'Two'`` و ``'Three'`` نگاشت شده‌اند. برای دستیابی هر مقدار شی دیکشنری ``dic`` از الگو ``[dic[key`` استفاده می‌کنیم که ``key`` در آن، کلید متصل به مقدار مورد نظر می‌باشد:: + + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d[0] + Traceback (most recent call last): + File "", line 1, in + KeyError: 0 + + >>> d[1] + 'One' + + >>> d[3][2:] + 'ree' + + +``[d[3`` اشاره به مقدار ``'Three'`` دارد؛ و از آنجا که این شی یک دنباله است می‌توان به روش دنباله‌ها (یعنی با استفاده از اندیس موقعیت) عضوهای این شی را نیز دستیابی نماییم. + + +به چند مثال دیگر توجه نمایید:: + + >>> d = {} # An empty dictionary + >>> d + {} + +:: + + >>> d = {'name': 'Bob', 'age': 40} + + >>> d['name'] + 'Bob' + >>> d['age'] + 40 + +:: + + >>> d = {'cb4f2': {'name': 'Bob', 'age': 40}} + + >>> d['cb4f2']['age'] + 40 + + + +ساختار نوع دیکشنری مشابه «جدول درهم‌سازی» (`Hash table `_) است و کاربرد‌های فراوانی در الگوریتم‌های جستجو دارد. از این نوع همچنین می‌توان برای سازماندهی و ذخیره داده‌ها بر روی فایل استفاده کرد؛ برای نمونه فرض کنید می‌خواهیم چند فیلم با بازی Benedict Cumberbatch را به گونه‌ای در اختیار داشته باشیم که بتوانیم آن‌ها را بر اساس سال ساخت دستیابی نماییم:: + + >>> benedict_cumberbatch = {'2014':'The Imitation Game', + ... '2013':('The Fifth Estate', '12 Years a Slave', 'Star Trek Into Darkness'), + ... '2012':'The Hobbit: An Unexpected Journey', + ... '2011':('War Horse', ' Wreckers', 'Tinker Tailor Soldier Spy')} + >>> + + >>> benedict_cumberbatch['2014'] + 'The Imitation Game' + + >>> len(benedict_cumberbatch['2011']) + 3 + + >>> benedict_cumberbatch['2011'][0] + 'War Horse' + + +از تابع ``()len`` نیز می‌توان برای به دست آوردن تعداد عضوهای شی دیکشنری (جفتِ کلید:مقدار) استفاده کرد:: + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> len(d) + 3 + +با انتساب یک مقدار جدید به یک کلید موجود از شی دیکشنری می‌توان مقدار آن کلید را تغییر داد و با انتساب یک مقدار به یک کلید جدید که در شی دیکشنری وجود ندارد یک عضو جدید به آن شی افزوده می‌شود:: + + >>> d = {'name': 'Bob', 'age': 40} + + >>> d['name'] = 'Jhon' + >>> d + {'name': 'Jhon', 'age': 40} + + >>> d['job'] = 'unemployed' + >>> d + {'name': 'Jhon', 'job': 'unemployed', 'age': 40} + +*برخلاف شی لیست یا تاپل (یا در کل دنباله‌ها) که داده‌هایی منظم (Ordered) هستند و ترتیب یا جایگاه قرار گرفتن عضوهای آن‌ها اهمیت دارد، یک شی دیکشنری این طور نیست و ترتیب عضوها در آن کاملا بی اهمیت است.* + +با استفاده از دستوری مشابه ``[del dic[key`` نیز می‌توان یک عضو شی دیکشنری را حذف کرد:: + + >>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40} + + >>> del d['job'] + >>> d + {'name': 'Jhon', 'age': 40} + + +امکانی برای تغییر کلیدها وجود ندارد مگر آنکه عضو مورد نظر را حذف کرده و یک عضو جدید (همان مقدار ولی با کلیدی جدید) اضافه نمایید:: + + >>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40} + + >>> d['occupation'] = d['job'] + >>> del d['job'] + + >>> d + {'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'} + +.. rubric:: عملگرها برای دیکشنری + +عملگرهای ``+`` و ``*`` برای اشیا دیکشنری تعریف **نشده‌اند**. + +از عملگرهای عضویت می‌توان برای بررسی وجود یک **کلید** در شی دیکشنری استفاده کرد:: + + >>> 'job' in {'name': 'Bob', 'age': 40} + False + + >>> 'job' not in {'name': 'Bob', 'age': 40} + True + +در مورد عملکرد عملگر برابری ``==`` و عملگرهای هویت (``is`` و ``is not``) صحبت شده است؛ این عملگرها برای اشیا دیکشنری نیز کاربرد دارند. + + +.. rubric:: کپی کردن + +همانطور که گفته شد شی دیکشنری از انواع «تغییر پذیر» پایتون است و همان توضیحاتی که در مورد شی لیست بیان شد؛ در اینجا هم درست است و گاهی نیاز می‌شود که از ماژول ``copy`` برای کپی اشیا دیکشنری استفاده نماییم: + +* بدون کپی کردن:: + + >>> d1 = {'name': 'Bob', 'age': 40} + + >>> d2 = d1 + + >>> d1 == d2 + True + >>> d1 is d2 + True + + >>> d1['age'] = 46 + + >>> d1 + {'name': 'Bob', 'age': 46} + >>> d2 + {'name': 'Bob', 'age': 46} + + +* کپی سطحی:: + + >>> d1 = {'name': 'Bob', 'age': 40} + + >>> import copy + >>> d2 = copy.copy(d1) # shallow copy + + >>> d1 == d2 + True + >>> d1 is d2 # False! + False + + >>> d1['age'] = 46 + + >>> d1 + {'name': 'Bob', 'age': 46} + >>> d2 + {'name': 'Bob', 'age': 40} + + :: + + >>> d1 = {'names': ['Bob', 'Jhon'], 'ages': [40, 40]} + + >>> import copy + >>> d2 = copy.copy(d1) # shallow copy + + >>> d1 == d2 + True + >>> d1 is d2 # False! + False + + >>> d1['ages'][0] = 46 + + >>> d1 + {'ages': [46, 40], 'names': ['Bob', 'Jhon']} + + >>> # d2 has changed! + >>> d2 + {'ages': [46, 40], 'names': ['Bob', 'Jhon']} + +* کپی عمیق:: + + >>> d1 = {'names': ['Bob', 'Jhon'], 'ages': [40, 40]} + + >>> import copy + >>> d2 = copy.deepcopy(d1) # deep copy + + >>> d1 == d2 + True + >>> d1 is d2 # False! + False + + >>> d1['ages'][0] = 46 + + >>> d1 + {'ages': [46, 40], 'names': ['Bob', 'Jhon']} + >>> d2 + {'ages': [40, 40], 'names': ['Bob', 'Jhon']} + + +.. rubric:: تبدیل به شی دیکشنری + +برای تبدیل دیگر اشیا به نوع دیکشنری یا در کل ایجاد شی دیکشنری از کلاس ``()dict`` [`اسناد پایتون `__] استفاده می‌شود. توجه داشته باشید که عضوهای شی دیکشنری از طریق آرگومان‌ها و به شکل «**کلید=مقدار**» به کلاس فرستاده می‌شوند:: + + >>> d = dict(one=1, two=2, three=3) + + >>> d + {'two': 2, 'one': 1, 'three': 3} + >>> d['one'] + 1 + +*در این حالت برای انتخاب کلیدها باید قوانین انتخاب نام در پایتون را رعایت نماییم؛ برای مثال کلیدی که با عدد شروع شود مجاز نمی‌باشد.* + +برای فرستادن کلیدها و مقدارها می‌توانیم از تابع ``()zip`` [`اسناد پایتون `__] استفاده کنیم و خروجی این تابع را به عنوان آرگومان به کلاس ``dict`` ارسال کنیم. می‌توان اینگونه تصور کرد که این تابع تعدادی شی دنباله را می‌گیرد و عضوهای نظیر به نظیر آن‌ها را در کنار هم قرار می‌دهد؛ این دنباله‌ها باید تعداد عضو برابری داشته باشند؛ چرا که عضوهای اضافی هر دنباله نادیده گرفته می‌شود. خروجی ``()zip`` یک شی جدید از نوع ``zip`` است و برای مشاهده معمولا آن را به نوع لیست تبدیل می‌کنند:: + + >>> k = [1, 2, 3, 4, 5] + >>> v = ['x', 'y', 'z'] + + >>> z = zip(k, v) + + >>> z + + + >>> type(z) + + + >>> list(z) + [(1, 'x'), (2, 'y'), (3, 'z')] + +:: + + >>> k = (1, 2, 3) + >>> v = ('One', 'Two', 'Three') + + >>> d = dict(zip(k, v)) + + >>> d + {1: 'One', 2: 'Two', 3: 'Three'} + +در آینده باز هم از تابع ``()zip`` استفاده خواهیم کرد. + + + + +.. rubric:: برخی از متدهای کاربردی یک شی دیکشنری + +* ``()items`` [`اسناد پایتون `__] تمام عضوهای شی را برمی‌گرداند - ``()values`` [`اسناد پایتون `__] تمام مقدارهای موجود در شی را بر می‌گرداند - ``()keys`` [`اسناد پایتون `__] تمام کلیدهای موجود در شی را بر می‌گرداند:: + + >>> # Python 3.x + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d.items() + dict_items([(1, 'One'), (2, 'Two'), (3, 'Three')]) + + >>> d.values() + dict_values(['One', 'Two', 'Three']) + + >>> d.keys() + dict_keys([1, 2, 3]) + + توجه داشته باشید که در نسخه‌های 3x پایتون خروجی این متدها از نوع متفاوتی است که با استفاده از ``()type`` می‌توانید مشاهده کنید؛ این نوع ``dict_view`` نامیده می‌شود [`اسناد پایتون 3x `__]. این متدها یک کپی از داده‌های مورد نظر (عضوها یا مقدارها یا کلیدها) را بر نمی‌گردانند بلکه می‌توان گفت پنجره‌ای برای مشاهده آنچه که هست باز می‌کنند و در هر زمان که این داده‌ها تغییر کنند این خروجی‌ها نیز تغییر می‌کنند. برای مشاهده بهتر این خروجی‌ها می‌توانید آن‌ها را به نوع لیست تبدیل نمایید:: + + >>> list(d.items()) + [(1, 'One'), (2, 'Two'), (3, 'Three')] + + >>> list(d.values()) + ['One', 'Two', 'Three'] + + >>> list(d.keys()) + [1, 2, 3] + + این متدها در پایتون 2x چنین خروجی ندارند و تنها یکی کپی از داده‌ها را برمی‌گردانند. البته در نسخه 2.7 متدهای معادلی با عنوان‌های ``()viewitems`` [`اسناد پایتون `__] و ``()viewvalues`` [`اسناد پایتون `__] و ``()viewkeys`` [`اسناد پایتون `__] پورت شده است:: + + >>> # Python 2.7 + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d.viewitems() + dict_items([(1, 'One'), (2, 'Two'), (3, 'Three')]) + + >>> d.viewvalues() + dict_values(['One', 'Two', 'Three']) + + >>> d.viewkeys() + dict_keys([1, 2, 3]) + + :: + + >>> # Python 2.x + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d.items() + [(1, 'One'), (2, 'Two'), (3, 'Three')] + + >>> d.values() + ['One', 'Two', 'Three'] + + >>> d.keys() + [1, 2, 3] + + + +* ``()clear`` [`اسناد پایتون `__] - تمام عضوهای یک شی دیکشنری را حذف می‌کند:: + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d.clear() + >>> d + {} + +* ``()copy`` [`اسناد پایتون `__] - این متد یک کپی سطحی از شی برمی‌گرداند:: + + >>> d1 = {'name':'Bob'} + + >>> d2 = d1.copy() + + >>> d1 is d2 + False + +* ``(fromkeys(seq`` [`اسناد پایتون `__] - یک دنباله از کلیدها را دریافت و یک شی جدید دیکشنری با استفاده از آن‌ها ایجاد می‌کند؛ البته کلیدهای این شی فاقد مقدار هستند که می‌بایست در زمانی دیگر به آن‌ها مقدار داد:: + + >>> k = (1, 2, 3) # or k=[1, 2, 3] or k='123' + + >>> dict.fromkeys(k) + {1: None, 2: None, 3: None} + + + توجه داشته باشید که این متد توسط خود کلاس ``dict`` فراخوانی می‌شود. + + این متد یک آرگومان اختیاری نیز دارد که توسط آن می‌توان یک شی را به عنوان «مقدار» پیش‌فرض کلید‌ها تعیین نمود:: + + >>> k = (1, 2, 3) + + >>> dict.fromkeys(k, '-*-') + {1: '-*-', 2: '-*-', 3: '-*-'} + +* ``(pop(key`` [`اسناد پایتون `__] - عضو دارنده کلید ``key`` را حذف و مقدار آن را برمی‌گرداند. چنانچه عضوی با این کلید یافت نشود شی پیش‌فرض تعیین شده (آرگومان دوم که اختیاری است) را برمی‌گرداند و اگر این آرگومان ارسال نشده باشد یک خطا گزارش می‌دهد:: + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d.pop(2) + 'Two' + >>> d + {1: 'One', 3: 'Three'} + + >>> d.pop(2) + Traceback (most recent call last): + File "", line 1, in + KeyError: 2 + + >>> d.pop(2, 'Oops!') + 'Oops!' + + + از این متد می‌توان برای تغییر راحت‌تر کلیدها استفاده کرد!:: + + >>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40} + + >>> d['occupation'] = d.pop('job') + + >>> d + {'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'} + + متد مشابه دیگری نیز با نام ``()popitem`` [`اسناد پایتون `__] - که بدون آرگومان است - در دسترس می‌باشد؛ این متد در هر فراخوانی یک عضو از شی مورد نظر را به صورت دلخواه حذف و به شکل تاپل (key, value) برمی‌گرداند و چنانچه دیکشنری خالی باشد یک خطا ``KeyError`` گزارش می‌دهد:: + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d.popitem() + (1, 'One') + +* ``(get(key`` [`اسناد پایتون `__] - مقدار مربوط به کلید ``key`` را برمی‌گرداند. چنانچه درون شی مورد نظر هیچ عضوی با این کلید وجود نداشته باشد شی پیش‌فرض تعیین شده (آرگومان دوم که اختیاری است) را برمی‌گرداند و اگر این آرگومان ارسال نشده باشد هیچ خطایی گزارش **نمی‌دهد**:: + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d.get(1) + 'One' + + >>> d.get(0) + >>> + + >>> d.get(0, False) + False + + +* ``(setdefault(key`` [`اسناد پایتون `__] - مقدار مربوط به کلید ``key`` را برمی‌گرداند. چنانچه عضوی با این کلید درون شی مورد نظر وجود نداشته باشد، کلید را به همراه مقدار پیش‌فرض تعیین شده (آرگومان دوم که اختیاری است) درون شی اضافه می‌کند و خود این مقدار را برمی‌گرداند؛ اگر آرگومان دوم ارسال نشده باشد به صورت پیش‌فرض مقدار ``None`` در نظر گرفته خواهد شد:: + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d.setdefault(1) + 'One' + >>> d + {1: 'One', 2: 'Two', 3: 'Three'} + + >>> d.setdefault(5) + >>> d + {1: 'One', 2: 'Two', 3: 'Three', 5: None} + + >>> d.setdefault(7, 'Seven') + 'Seven' + >>> d + {1: 'One', 2: 'Two', 3: 'Three', 5: None, 7: 'Seven'} + + + +* ``()update`` [`اسناد پایتون `__] - یک شی دیکشنری دیگر را به عنوان آرگومان می‌گیرد و عضوهای شی مورد نظر را بر اساس آن تغییر می‌دهد:: + + >>> d = {1:'One', 2:'Two', 3:'Three'} + + >>> d2 = {5:'Five', 6:'Six'} + >>> d.update(d2) + >>> d + {1: 'One', 2: 'Two', 3: 'Three', 5: 'Five', 6: 'Six'} + + >>> d3 = {1:'0001'} + >>> d.update(d3) + >>> d + {1: '0001', 2: 'Two', 3: 'Three', 5: 'Five', 6: 'Six'} + + + +مجموعه +-------- + +«**مجموعه**» (Set) از انواع «نامنظم» (Unordered) و «تغییر پذیر» (Mutable) پایتون است که معادل مفهوم مجموعه در ریاضیات می‌باشد. **هر عضو مجموعه می‌بایست یکتا و یکی از انواع «تغییر ناپذیر» باشد**. نوع مجموعه یا ``set`` در نسخه‌ 3x با کمی تفاوت ارایه شده است. در نسخه‌های 2x تنها می‌توان با استفاده از کلاس ``()set`` [`اسناد پایتون `__] اقدام به ایجاد این اشیا نمود در حالی که در پایتون 3x این کار به سادگی و تنها با استفاده از نماد آکولاد ``{ }`` نیز امکان پذیر شده است؛ (البته این ویژگی به نسخه 2.7 هم پورت شده است). در دو نمونه کد پایین به چگونگی تعریف و نمایش شی مجموعه توجه نمایید: + +*نسخه‌های 2x:* + +:: + + >>> L = [1, 2, 3, 4, 5] + + >>> s = set(L) + + >>> type(s) + + + >>> s + set([1, 2, 3, 4, 5]) + + >>> print s + set([1, 2, 3, 4, 5]) + +:: + + >>> s = {1, 2, 3, 4, 5} # Python 2.7 + + >>> type(s) + + + >>> s + set([1, 2, 3, 4, 5]) + + +*نسخه‌های 3x:* + +:: + + >>> L = [1, 2, 3, 4, 5] + + >>> s = set(L) + + >>> type(s) + + + >>> s + {1, 2, 3, 4, 5} + + >>> print(s) + {1, 2, 3, 4, 5} + +:: + + >>> s = {1, 2, 3, 4, 5} + + >>> type(s) + + + >>> s + {1, 2, 3, 4, 5} + +هیچ سینتکس خاصی برای ایجاد یا بیان یک شی خالی از نوع مجموعه وجود ندارد و تنها می‌بایست از کلاس ``()set`` - بدون آرگومان - استفاده کرد. توجه داشته باشید که ``{}`` بیانگر یک شی دیکشنری خالی است و نه یک مجموعه خالی:: + + >>> a = {} # Python 2.x + >>> type(a) + + + >>> b = set() + >>> type(b) + + + >>> b + set([]) + +:: + + >>> a = {} # Python 3.x + >>> type(a) + + + >>> b = set() + >>> type(b) + + + >>> b + set() + + +از تابع ``()len`` می‌توان برای به دست آوردن تعداد عضوهای یک شی مجموعه نیز استفاده کرد:: + + >>> s = {1, 2, 3, 4, 5} + >>> len(s) + 5 + + + +.. rubric:: عملگرها برای مجموعه + +تعدادی از عملگرها هستند که برای اشیا مجموعه تعریف خاصی پیدا می‌کنند؛ در حالی که در مورد اشیا دیگر چنین رفتاری ندارند. این عملگرها در واقع پیاده‌سازی تعریف مشخصی در مفهوم ریاضی مجموعه‌ها هستند: + +* ``|`` اجتماع (Union): مانند ``A | B`` که حاصل آن مجموعه‌ای می‌باشد که تمام عضوهای مجموعه ``A`` و مجموعه ``B`` را داشته باشد و هیچ عضو اضافه دیگری نداشته باشد. + + >>> A | B + {'w', 'y', 'q', 't', 'r', 'z', 's', 'v', 'u', 'x'} + +* ``&`` اشتراک (Intersection): مانند ``A & B`` که حاصل آن مجموعه‌ای می‌باشد که تنها شامل عضوهایی است که هم در مجموعه ``A`` هستند و هم در مجموعه ``B``:: + + >>> A & B + {'w', 'v', 'u'} + + +* ``-`` تفاضل (Difference): مانند ``A - B`` که حاصل آن مجموعه‌ای می‌باشد که تنها شامل عضوهایی از مجموعه ``A`` است كه در مجموعه ``B`` نيستند:: + + >>> A = {'u', 'v', 'w', 'x', 'y', 'z'} + >>> B = {'q', 'r', 's', 't', 'u', 'v', 'w',} + + >>> A - B + {'z', 'y', 'x'} + + +* ``^`` تفاضل متقارن (Symmetric difference): مانند ``A ^ B`` که حاصل آن مجموعه‌ای می‌باشد که برابر اجتماع ِ تفاضل ``A`` از ``B`` و تفاضل ``B`` از ``A`` می‌باشد یعنی: ``(A-B) | (B-A)``:: + + >>> A ^ B + {'q', 'y', 't', 'r', 'z', 's', 'x'} + + :: + + >>> (A-B) | (B-A) + {'y', 'q', 't', 'r', 'z', 'x', 's'} + + + تفاضل متقارن را می‌توان به صورت پایین نیز تعریف کرد:: + + >>> (A|B) - (B&A) + {'y', 'q', 't', 'r', 'z', 's', 'x'} + +* ``>`` زیرمجموعه (Subset): مانند ``A < B`` که اگر مجموعه ``A`` زیرمجموعه‌ای از مجموعه ``B`` باشد مقدار ``True`` را برمی‌گرداند. در مقابل عملگر ``<`` قرار دارد که برای مثال در عبارت ``A > B`` اگر مجموعه ``A`` یک Superset برای مجموعه ``B`` باشد مقدار ``True`` را برمی‌گرداند:: + + >>> A = {1, 2, 3, 4, 5} + >>> B = {1, 2, 3} + + >>> A < B + False + + >>> A > B + True + +برخی از عملگرهای عمومی نیز برای اشیا مجموعه قابل استفاده هستند:: + + >>> A = {'a', 'b', 'c'} + + >>> 'a' in A + True + >>> 'c' not in A + False + +:: + + >>> A = {1, 2, 3, 4, 5} + >>> B = {1, 2, 3} + + >>> A == B + False + + >>> C = A + + >>> A == C + True + + >>> A is C + True + +.. rubric:: برخی از متدهای کاربردی یک شی مجموعه + + +* ``()union`` [`اسناد پایتون `__] - تعدادی شی مجموعه را دریافت می‌کند و یک مجموعه جدید که برابر اجتماع شی مورد نظر با آن‌ها است را برمی‌گرداند:: + + >>> A = {'a', 'b', 'c'} + >>> B = {1, 2, 3} + + >>> {'t', 1, 'a'}.union(A, B) + {'a', 1, 2, 3, 't', 'b', 'c'} + + >>> {'t', 1, 'a'} | A | B + {1, 2, 3, 'b', 't', 'a', 'c'} + + به صورت مشابه می‌توان از متدهای ``()intersection`` [`اسناد پایتون `__] برای اشتراک، ``()difference`` [`اسناد پایتون `__] برای تفاضل، ``()symmetric_difference`` [`اسناد پایتون `__] - که تک آرگومانی است - برای تفاضل متقارن، ``()issubset`` [`اسناد پایتون `__] و ``()issuperset`` [`اسناد پایتون `__] - که هر دو تک آرگومانی هستند - برای بررسی زیرمجموعه یا Superset بودن استفاده کرد. + + + +* ``()clear`` [`اسناد پایتون `__] - تمام عضوهای یک شی مجموعه را حذف می‌کند:: + + >>> A = {'a', 'b', 'c'} + + >>> A.clear() + >>> A + set() + +* ``(add(x`` [`اسناد پایتون `__] - شی تغییر ناپذیر ``x`` را در صورتی که از قبل درون شی مجموعه مورد نظر وجود نداشته باشد به آن اضافه می‌کند:: + + >>> A = {'a', 'b', 'c'} + + >>> A.add(1) + >>> A + {'a', 'c', 1, 'b'} + +* ``(remove(x`` [`اسناد پایتون `__] - عضو ``x`` را از شی مجموعه مورد نظر حذف می‌کند. در صورتی که ``x`` درون مجموعه وجود نداشته باشد یک خطا گزارش می‌دهد:: + + >>> A = {'a', 'b', 'c', 1} + + >>> A.remove(1) + >>> A + {'c', 'a', 'b'} + + >>> A.remove(1) + Traceback (most recent call last): + File "", line 1, in + KeyError: 1 + + + متد مشابه دیگری نیز با الگو ``(discard(x`` [`اسناد پایتون `__] وجود دارد که این متد چنانچه ``x`` وجود داشته باشد آن را حذف می‌کند؛ بنابرین در صورت نبودن ``x`` خطایی گزارش نمی‌گردد:: + + >>> A = {'c', 'a', 'b'} + + >>> A.discard(1) + >>> A + {'b', 'a', 'c'} + + + +* ``()pop`` [`اسناد پایتون `__] - این متد آرگومانی ندارد و به صورت دلخواه یک عضو از مجموعه را حذف و به عنوان خروجی برمی‌گرداند. در مواردی که مجموعه خالی باشد یک خطا گزارش می گردد:: + + >>> A = {'a', 'b', 'c'} + + >>> A.pop() + 'a' + + :: + + >>> A.pop() + Traceback (most recent call last): + File "", line 1, in + KeyError: 'pop from an empty set' + + +.. rubric:: frozenset + +همانطور که پیش از این بیان شد مجموعه یک شی «تغییر پذیر» است با عضوهای «تغییر ناپذیر» و به دلیل همین تغییر پذیری است که می‌توانیم به سادگی توسط متدها عضوی به آن افزوده یا حذف نماییم. **”frozenset“** یک نوع جدید مجموعه است. همانگونه که می‌توانیم یک شی تاپل را معادل یک شی لیست تغییر ناپذیر تصویر کنیم؛ frozenset را نیز می‌توان **یک شی مجموعه تغییر ناپذیر** تصور کرد. نوع ``frozenset`` همان نوع ``set`` است، با تمام ویژگی‌های آن به غیر از تغییر پذیری که با استفاده از کلاس ``()frozenset`` ایجاد می‌گردد: + +*نسخه‌های 2x:* + +:: + + >>> L = [1, 2, 3] + + >>> A = frozenset(L) + + >>> type(A) + + + >>> A + frozenset([1, 2, 3]) + +*نسخه‌های 3x:* + +:: + + >>> L =[1, 2, 3] + + >>> A = frozenset(L) + + >>> type(A) + + + >>> A + frozenset({1, 2, 3}) + +با استفاده از تابع ``()dir`` می‌توان متوجه متدهای در دسترس شی ``frozenset`` شد:: + + >>> dir(frozenset) # Python 3.x + ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union'] + + +NoneType +---------- + +این نوع شی فاقد مقدار است و با انتساب ثابت ``None`` [`اسناد پایتون `__] به یک نام ایجاد می‌گردد:: + + >>> n = None + + >>> type(n) + + + >>> print(n) + None + + >>> import sys + >>> sys.getsizeof(a) + 16 + + >>> n = 5 + >>> type(n) + + +``None`` در پایتون 3x جزو کلمه‌های کلیدی (keywords) تعریف شده است. + + +دسته‌بندی +----------- + +در این بخش به دسته‌بندی انواع شی بر اساس برخی از تعریف‌های پایتون پرداخته شده است. + + +* انواع عددی (Numeric Types): + + .. code-block:: html + :linenos: + + - int + - long (2.x) + - float + - complex + - Decimal + - Fraction + - bool + +* انواع دنباله (Sequence Types): + + .. code-block:: html + :linenos: + + - str + - unicode (2.x) + - bytes (3.x) + - bytearray (3.x/2.6+) + - tuple + - list + +* انواع تغییر ناپذیر (Immutable Types): + + .. code-block:: html + :linenos: + + - int + - long (2.x) + - float + - complex + - Decimal + - Fraction + - bool + - str + - unicode (2.x) + - bytes (3.x) + - tuple + - frozenset + + +* انواع تغییر پذیر (Mutable Types): + + .. code-block:: html + :linenos: + + - bytearray (3.x/2.6+) + - list + - dict + - set + +* انواع نگاشت (Mapping Types): + + .. code-block:: html + :linenos: + + - dict + +* انواع مجموعه (Set Types): + + .. code-block:: html + :linenos: + + - set + - frozenset + + +* برخی دیگر: + + .. code-block:: html + :linenos: + + - zip + - dict_views + - NoneType + +*در درس‌های بعد نیز با انواع آماده (Built-in) دیگری آشنا خواهیم شد.* + +| + +---- + +:emoji-size:`😊` امیدوارم مفید بوده باشه + + From f340379e9217ba08cb879601f0ba3c3eb6bff795 Mon Sep 17 00:00:00 2001 From: Saeid Date: Sun, 16 Apr 2023 10:07:17 +0430 Subject: [PATCH 2/5] edited l08.1 --- .../lessons/l08-list-and-tuple-in-python.rst | 53 +++++++++++++------ source/lessons/l08-set-and-dict-in-python.rst | 8 +-- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/source/lessons/l08-list-and-tuple-in-python.rst b/source/lessons/l08-list-and-tuple-in-python.rst index c19806a..9d9d191 100644 --- a/source/lessons/l08-list-and-tuple-in-python.rst +++ b/source/lessons/l08-list-and-tuple-in-python.rst @@ -1,18 +1,18 @@ .. role:: emoji-size .. meta:: - :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان داده در پایتون، list و tuple - :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان داده در پایتون, list در پایتون, tuple در پایتون + :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان‌های داده در پایتون، list و tuple + :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان‌های داده در پایتون, list در پایتون, tuple در پایتون .. _lesson-08.1: -درس ۰۸: ساختمان داده در پایتون: list و tuple +درس ۰۸: ساختمان‌های داده در پایتون: list و tuple ==================================================================================== .. figure:: /_static/pages/08-python-built-in-data-types-2.jpg :align: center - :alt: درس ۰۸: ساختمان داده در پایتون: tuple و list + :alt: درس ۰۸: ساختمان‌های داده در پایتون: tuple و list :class: page-image Photo by `Natalia Y `__ @@ -35,11 +35,12 @@ ---- +.. _python-list: لیست ------ -نوع «**لیست**» (List) انعطاف‌ پذیرترین نوع آماده در پایتون می‌باشد. این نوع همانند رشته یک «**دنباله**» (Sequence) بوده ولی برخلاف آن یک نوع «**تغییر پذیر**» (Mutable) است. شی لیست با استفاده از کروشه ``[ ]`` ایجاد می‌گردد و می‌تواند عضوهایی - **با هر نوع** - داشته باشد که توسط کاما ``,`` از یکدیگر جدا می‌شوند؛ نوع لیست در واقع محلی برای نگهداری اشیا گوناگون است:: +نوع «**لیست**» (List) انعطاف‌ پذیرترین نوع آماده در پایتون می‌باشد. این نوع همانند رشته یک «**دنباله**» (Sequence) بوده ولی برخلاف آن یک نوع «**تغییر پذیر**» (Mutable) است. شی لیست با استفاده از کروشه ``[ ]`` ایجاد می‌گردد و ترتیب اعضا را حفظ و می‌تواند عضوهایی - **از هر نوع** - داشته باشد که توسط کاما ``,`` از یکدیگر جدا می‌شوند؛ نوع لیست در واقع محلی برای نگهداری اشیا گوناگون و تغییرپذیر است:: >>> L = [1, 2, 3] >>> type(L) @@ -169,8 +170,11 @@ >>> L [0, 1, 5, 6] + +.. _python-del: -.. rubric:: دستور ``del`` +دستور ``del`` +~~~~~~~~~~~~~~~~~ با استفاده از دستور ``del`` [`اسناد پایتون `__] نیز می‌توان یک عضو یا یک تکه از شی لیست را حذف کرد:: @@ -184,7 +188,7 @@ >>> L ['a', 'f', 'g'] -همچنین می‌توانیم از این دستور برای حذف کامل یک متغیر استفاده نماییم. با حدف یک متغیر، ارجاع آن به شی نیز حذف می‌شود و چنانچه هیچ ارجاع دیگری به آن شی وجود نداشته باشد، شی‌ای که متغیر به آن ارجاع داشت نیز حذف می‌گردد:: +همچنین می‌توانیم از این دستور برای حذف کامل یک متغیر استفاده نماییم. با حدف یک متغیر، ارجاع آن به شی نیز حذف می‌شود و چنانچه هیچ ارجاع دیگری به آن شی وجود نداشته باشد، شی‌ای که متغیر به آن ارجاع داشت نیز از حافظه حذف می‌گردد:: >>> a = 5 >>> a @@ -267,8 +271,11 @@ >>> d [4.4] + +.. _python-copy: -.. rubric:: کپی کردن +کپی کردن +~~~~~~~~~~~~~~~~ همانند دیگر اشیا می‌توان با انتساب یک متغیر موجود از شی لیست به یک نام جدید، متغیر دیگری از این نوع شی ایجاد کرد. البته همانطور که پیش‌تر نیز بیان شده است؛ در این حالت شی کپی نمی‌گردد و تنها یک ارجاع جدید از این نام جدید به شی آن متغیر داده می‌شود. این موضوع با استفاده از تابع ``()id`` [`اسناد پایتون `__] قابل آزمودن است؛ خروجی این تابع برابر نشانی شی در حافظه می‌باشد و بدیهی است که دو مقدار id یکسان برای دو متغیر نشان از یکی بودن شی آن‌هاست:: @@ -393,7 +400,11 @@ >>> id(L2[2]) 140402651379080 -.. rubric:: عملگرها برای لیست + +.. _python-list-operators: + +عملگرها برای لیست +~~~~~~~~~~~~~~~~~~~~~~~~~ می‌توان از عملگرهای ``+`` (برای پیوند لیست‌ها) و ``*`` (برای تکرار عضوهای لیست) بهره برد:: @@ -423,7 +434,11 @@ >>> [1, 2] in L True -.. rubric:: تفاوت عملگرهای ``==`` و ``is`` + +.. _python-is-va-equal: + +تفاوت عملگرهای ``==`` و ``is`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ نکته‌ای که در درس‌های پیش مطرح نشد، بیان تفاوت بین عملگر برابری و عملگر هویت است. پیش از ارایه توضیح به نمونه کد پایین توجه نمایید:: @@ -473,8 +488,10 @@ >>> L1 is L2 # False! False +.. _python-convert-to-list: -.. rubric:: تبدیل به شی لیست +تبدیل به شی لیست +~~~~~~~~~~~~~~~~~~~~~~~~~ با استفاده از کلاس ``()list`` [`اسناد پایتون `__] می‌توان یک شی لیست ایجاد کرد یا اشیایی که از نوع دنباله هستند را به یک شی لیست تبدیل نمود:: @@ -496,9 +513,10 @@ [] +.. _python-list-methods: - -.. rubric:: متدهای کاربردی یک شی لیست +متدهای کاربردی یک شی لیست +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ شی لیست تغییر پذیر است و متدهای آن برخلاف شی رشته یک شی جدید تغییر یافته را برنمی‌گردانند بلکه تغییرات را بر روی همان شی ایجاد می‌کنند. @@ -514,7 +532,7 @@ >>> L [1, 2, 3, 4, ['a', 'b']] - عملکرد این متد (``(L.append(x``) همانند عمل ``[L + [x`` است:: + عملکرد این متد ``(L.append(x`` همانند عمل ``[L + [x`` است:: >>> L = [1, 2, 3] >>> L + [4] @@ -538,7 +556,7 @@ [1, 2, 3, 'p', 'y'] -* ``(insert(i, x`` - یک عضو جدید (مانند ``x``) را در موقعیتی از لیست با اندیس دلخواه (مانند ``i``) قرار می‌دهد:: +* ``(insert(i, x`` - یک عضو جدید مانند ``x`` را در موقعیتی از لیست با اندیس دلخواه مانند ``i`` قرار می‌دهد:: >>> L = [1, 2, 3] @@ -700,8 +718,11 @@ >>> sorted(L, key=str.lower, reverse=True) ['h', 'G', 'f', 'e', 'D', 'c', 'B', 'a'] + +.. _python-stack-with-list: -.. rubric:: ایجاد پشته +ایجاد پشته +~~~~~~~~~~~~~~~~~ «پشته» (`Stack `_) ساختاری برای نگهداری موقت داده‌ها می‌باشد به شکلی که آخرین داده‌ای که در آن قرار می‌گیرد نخستین داده‌ای خواهد بود که خارج می‌گردد؛ این شیوه سازمان‌دهی LIFO یا Last In, First Out خوانده می‌شود. پشته تنها از دو عمل (یا متد) پشتیبانی می‌کند: **push** که داده‌ای را بالای تمام داده‌های موجود در آن قرار می‌دهد و **pop** که بالاترین داده را از آن خارج می‌کند. diff --git a/source/lessons/l08-set-and-dict-in-python.rst b/source/lessons/l08-set-and-dict-in-python.rst index dc4c139..d1d9fa1 100644 --- a/source/lessons/l08-set-and-dict-in-python.rst +++ b/source/lessons/l08-set-and-dict-in-python.rst @@ -1,16 +1,16 @@ .. role:: emoji-size .. meta:: - :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان داده در پایتون، set و dict - :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان داده در پایتون, set در پایتون, dict در پایتون + :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان‌های داده در پایتون، set و dict + :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان‌های داده در پایتون, set در پایتون, dict در پایتون -درس ۰۸: ساختمان داده در پایتون: set و dict +درس ۰۸: ساختمان‌های داده در پایتون: set و dict ==================================================================================== .. figure:: /_static/pages/08-python-built-in-data-types-2.jpg :align: center - :alt: درس ۰۸: ساختمان داده در پایتون: set و dict + :alt: درس ۰۸: ساختمان‌های داده در پایتون: set و dict :class: page-image Photo by `Natalia Y `__ From e3efcaa37e3c1e77d8478c5190ba744feb977f89 Mon Sep 17 00:00:00 2001 From: Saeid Date: Mon, 17 Apr 2023 10:12:51 +0430 Subject: [PATCH 3/5] edited l08.2 - dict --- source/lessons/l08-set-and-dict-in-python.rst | 125 +++++++++++------- 1 file changed, 75 insertions(+), 50 deletions(-) diff --git a/source/lessons/l08-set-and-dict-in-python.rst b/source/lessons/l08-set-and-dict-in-python.rst index d1d9fa1..ad51133 100644 --- a/source/lessons/l08-set-and-dict-in-python.rst +++ b/source/lessons/l08-set-and-dict-in-python.rst @@ -4,6 +4,9 @@ :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان‌های داده در پایتون، set و dict :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان‌های داده در پایتون, set در پایتون, dict در پایتون + + +.. _lesson-08.2: درس ۰۸: ساختمان‌های داده در پایتون: set و dict ==================================================================================== @@ -32,10 +35,12 @@ ---- +.. _python-dict: + دیکشنری --------- -یکی دیگر از انواع انعطاف پذیر آماده در پایتون «**دیکشنری**» (Dictionary) می‌باشد که با نام کوتاه شده ``dict`` ارایه شده است. اشیا نوع دیکشنری با استفاده از نماد آکولاد ``{ }`` معرفی‌ می‌شوند و هر داده در آن به شکل یک جفت «**کلید:مقدار**» (key:value) ذخیره می‌گردد. از این نوع شی با عنوان شی mapping (نگاشت) پایتون نیز یاد می‌شود چرا که در این نوع هر شی «کلید» به یک شی «مقدار» map یا نگاشت داده می‌شود. شی دیکشنری دنباله نیست ولی تغییر پذیر بوده و «مقدار» هر عضو توسط «کلید» متناظر با آن دستیابی می‌شود. شی «مقدار» می‌تواند از هر نوعی باشد حتی یک شی دیکشنری دیگر ولی شی «کلید» تنها می‌بایست از انواع «تغییر ناپذیر» انتخاب شود و باید توجه داشت که تمام «کلید»‌های یک شی دیکشنری می‌بایست «**یکتا**» (Unique) باشند. +یکی دیگر از انواع ساختمان‌های داده در پایتون «**دیکشنری**» (Dictionary) می‌باشد که با نام کوتاه شده ``dict`` ارایه شده است. اشیا نوع دیکشنری با استفاده از نماد آکولاد ``{ }`` معرفی‌ می‌شوند و هر داده در آن به شکل یک جفت «**کلید:مقدار**» (key:value) ذخیره می‌گردد. از این نوع شی با عنوان شی mapping (نگاشت) پایتون نیز یاد می‌شود چرا که در این نوع هر شی «کلید» به یک شی «مقدار» map یا نگاشت داده می‌شود. شی دیکشنری **دنباله نیست** و هر عضو آن به جای اندیس با استفاده از کلید دستیابی می‌شود. دیکشنری در پایتون **تغییر پذیر** است و شی «مقدار» می‌تواند از هر نوعی باشد حتی یک شی دیکشنری دیگر ولی شی «کلید» تنها می‌بایست از انواع «تغییرناپذیر» انتخاب شود و باید توجه داشت که تمام «کلید»‌های یک شی دیکشنری می‌بایست «**یکتا**» (Unique) باشند. از **نسخه 3.7 پایتون**، دیکشنری قابلیت حفظ ترتیب عناصر خود را نیز دارد یا به اصطلاح Ordered است. :: @@ -96,6 +101,20 @@ >>> d['cb4f2']['age'] 40 + +برای ایجاد شی دیکشنری می‌توان از کلاس ``()dict`` [`اسناد پایتون `__] نیز استفاده نمود:: + + + >>> d = dict(one=1, two=2, three=3) + + >>> d + {'two': 2, 'one': 1, 'three': 3} + >>> d['one'] + 1 + +توجه داشته باشید که عضوهای شی دیکشنری از طریق آرگومان‌ها و به شکل «**کلید=مقدار**» به کلاس فرستاده می‌شوند و در این حالت برای انتخاب کلیدها باید قوانین انتخاب نام در پایتون را رعایت نماییم؛ برای مثال کلیدی که با عدد شروع شود مجاز نمی‌باشد. + + ساختار نوع دیکشنری مشابه «جدول درهم‌سازی» (`Hash table `_) است و کاربرد‌های فراوانی در الگوریتم‌های جستجو دارد. از این نوع همچنین می‌توان برای سازماندهی و ذخیره داده‌ها بر روی فایل استفاده کرد؛ برای نمونه فرض کنید می‌خواهیم چند فیلم با بازی Benedict Cumberbatch را به گونه‌ای در اختیار داشته باشیم که بتوانیم آن‌ها را بر اساس سال ساخت دستیابی نماییم:: @@ -133,13 +152,12 @@ >>> d['job'] = 'unemployed' >>> d - {'name': 'Jhon', 'job': 'unemployed', 'age': 40} + {'name': 'Jhon', 'age': 40, 'job': 'unemployed'} -*برخلاف شی لیست یا تاپل (یا در کل دنباله‌ها) که داده‌هایی منظم (Ordered) هستند و ترتیب یا جایگاه قرار گرفتن عضوهای آن‌ها اهمیت دارد، یک شی دیکشنری این طور نیست و ترتیب عضوها در آن کاملا بی اهمیت است.* با استفاده از دستوری مشابه ``[del dic[key`` نیز می‌توان یک عضو شی دیکشنری را حذف کرد:: - >>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40} + >>> d = {'name': 'Jhon', 'age': 40, 'job': 'unemployed'} >>> del d['job'] >>> d @@ -148,15 +166,19 @@ امکانی برای تغییر کلیدها وجود ندارد مگر آنکه عضو مورد نظر را حذف کرده و یک عضو جدید (همان مقدار ولی با کلیدی جدید) اضافه نمایید:: - >>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40} + >>> d = {'name': 'Jhon', 'age': 40, 'job': 'unemployed'} >>> d['occupation'] = d['job'] >>> del d['job'] >>> d {'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'} + -.. rubric:: عملگرها برای دیکشنری +.. _python-dict-operators: + +عملگرها برای دیکشنری +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ عملگرهای ``+`` و ``*`` برای اشیا دیکشنری تعریف **نشده‌اند**. @@ -171,7 +193,10 @@ در مورد عملکرد عملگر برابری ``==`` و عملگرهای هویت (``is`` و ``is not``) صحبت شده است؛ این عملگرها برای اشیا دیکشنری نیز کاربرد دارند. -.. rubric:: کپی کردن +.. _python-dict-copy: + +کپی کردن +~~~~~~~~~~~~~~~~~~ همانطور که گفته شد شی دیکشنری از انواع «تغییر پذیر» پایتون است و همان توضیحاتی که در مورد شی لیست بیان شد؛ در اینجا هم درست است و گاهی نیاز می‌شود که از ماژول ``copy`` برای کپی اشیا دیکشنری استفاده نماییم: @@ -253,21 +278,47 @@ >>> d2 {'ages': [40, 40], 'names': ['Bob', 'Jhon']} + +.. _python-convert-to-dict: -.. rubric:: تبدیل به شی دیکشنری +تبدیل به شی دیکشنری +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -برای تبدیل دیگر اشیا به نوع دیکشنری یا در کل ایجاد شی دیکشنری از کلاس ``()dict`` [`اسناد پایتون `__] استفاده می‌شود. توجه داشته باشید که عضوهای شی دیکشنری از طریق آرگومان‌ها و به شکل «**کلید=مقدار**» به کلاس فرستاده می‌شوند:: +برای تبدیل دیگر اشیا به نوع دیکشنری یا در کل ایجاد شی دیکشنری از کلاس ``()dict`` [`اسناد پایتون `__] استفاده می‌شود. - >>> d = dict(one=1, two=2, three=3) - >>> d - {'two': 2, 'one': 1, 'three': 3} - >>> d['one'] - 1 +برای تبدیل اشیا دنباله به مانند لیست و تاپل به دیکشنری می‌بایست از ساختار تودرتو استفاده کرد، به گونه‌ای که هر عضو این ساختمان‌ها خود شامل دو عضو باشد:: + + >>> t = ('one', 'two', 'three') + >>> type(t) + + + >>> d = dict(t) + Traceback (most recent call last): + File "", line 1, in + ValueError: dictionary update sequence element #0 has length 3; 2 is required + +:: + + >>> t = ((1, 'one'), (2, 'two'), (3, 'three')) + >>> dict(t) + {1: 'one', 2: 'two', 3: 'three'} + >>> + + +البته می‌توان از یک مقدار پیش‌فرض نیز برای تبدیل نوع سریع آن‌ها به روش زیر بهره برد:: -*در این حالت برای انتخاب کلیدها باید قوانین انتخاب نام در پایتون را رعایت نماییم؛ برای مثال کلیدی که با عدد شروع شود مجاز نمی‌باشد.* -برای فرستادن کلیدها و مقدارها می‌توانیم از تابع ``()zip`` [`اسناد پایتون `__] استفاده کنیم و خروجی این تابع را به عنوان آرگومان به کلاس ``dict`` ارسال کنیم. می‌توان اینگونه تصور کرد که این تابع تعدادی شی دنباله را می‌گیرد و عضوهای نظیر به نظیر آن‌ها را در کنار هم قرار می‌دهد؛ این دنباله‌ها باید تعداد عضو برابری داشته باشند؛ چرا که عضوهای اضافی هر دنباله نادیده گرفته می‌شود. خروجی ``()zip`` یک شی جدید از نوع ``zip`` است و برای مشاهده معمولا آن را به نوع لیست تبدیل می‌کنند:: + >>> t = ('one', 'two', 'three') + >>> dict.fromkeys(t, "-") + {'one': '-', 'two': '-', 'three': '-'} + + >>> dict.fromkeys("Python", "-") + {'P': '-', 'y': '-', 't': '-', 'h': '-', 'o': '-', 'n': '-'} + + + +اما روش ساده‌تر، استفاده از تابع ``()zip`` [`اسناد پایتون `__] است. می‌توان اینگونه تصور کرد که این تابع تعدادی شی دنباله را می‌گیرد و عضوهای نظیر به نظیر آن‌ها را در کنار هم قرار می‌دهد؛ این دنباله‌ها باید تعداد عضو برابری داشته باشند؛ چرا که عضوهای اضافی هر دنباله نادیده گرفته می‌شود. خروجی ``()zip`` یک شی جدید از نوع ``zip`` است و می‌توان آن را به عنوان آرگومان به کلاس ``dict`` ارسال کنیم:: >>> k = [1, 2, 3, 4, 5] >>> v = ['x', 'y', 'z'] @@ -296,9 +347,10 @@ در آینده باز هم از تابع ``()zip`` استفاده خواهیم کرد. +.. _python-dict-methods: - -.. rubric:: برخی از متدهای کاربردی یک شی دیکشنری +برخی از متدهای کاربردی یک شی دیکشنری +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``()items`` [`اسناد پایتون `__] تمام عضوهای شی را برمی‌گرداند - ``()values`` [`اسناد پایتون `__] تمام مقدارهای موجود در شی را بر می‌گرداند - ``()keys`` [`اسناد پایتون `__] تمام کلیدهای موجود در شی را بر می‌گرداند:: @@ -475,43 +527,16 @@ {1: '0001', 2: 'Two', 3: 'Three', 5: 'Five', 6: 'Six'} - -مجموعه --------- - -«**مجموعه**» (Set) از انواع «نامنظم» (Unordered) و «تغییر پذیر» (Mutable) پایتون است که معادل مفهوم مجموعه در ریاضیات می‌باشد. **هر عضو مجموعه می‌بایست یکتا و یکی از انواع «تغییر ناپذیر» باشد**. نوع مجموعه یا ``set`` در نسخه‌ 3x با کمی تفاوت ارایه شده است. در نسخه‌های 2x تنها می‌توان با استفاده از کلاس ``()set`` [`اسناد پایتون `__] اقدام به ایجاد این اشیا نمود در حالی که در پایتون 3x این کار به سادگی و تنها با استفاده از نماد آکولاد ``{ }`` نیز امکان پذیر شده است؛ (البته این ویژگی به نسخه 2.7 هم پورت شده است). در دو نمونه کد پایین به چگونگی تعریف و نمایش شی مجموعه توجه نمایید: - -*نسخه‌های 2x:* - -:: - - >>> L = [1, 2, 3, 4, 5] - - >>> s = set(L) - - >>> type(s) - - - >>> s - set([1, 2, 3, 4, 5]) - - >>> print s - set([1, 2, 3, 4, 5]) - -:: - - >>> s = {1, 2, 3, 4, 5} # Python 2.7 - >>> type(s) - - >>> s - set([1, 2, 3, 4, 5]) +.. _python-set: + +مجموعه +-------- -*نسخه‌های 3x:* +«**مجموعه**» (Set) از انواع «بدون ترتیب» (Unordered) و «تغییر پذیر» (Mutable) پایتون است که برابر مفهوم مجموعه در ریاضیات می‌باشد. **هر عضو مجموعه می‌بایست یکتا و یکی از انواع «تغییر ناپذیر» باشد**. نوع مجموعه یا ``set`` را می‌توان با استفاده از کلاس ``()set`` [`اسناد پایتون `__] یا تنها با استفاده از نماد آکولاد ``{ }`` ایجاد کرد:: -:: >>> L = [1, 2, 3, 4, 5] From 35d1fbc96605fb8a87e8dcee7f78c7c16a2b1f21 Mon Sep 17 00:00:00 2001 From: Saeid Darvish Date: Wed, 19 Apr 2023 00:32:06 +0330 Subject: [PATCH 4/5] edited l08.2 - completed --- source/lessons/l06-python-syntax.rst | 28 ++++ source/lessons/l08-set-and-dict-in-python.rst | 150 ++++-------------- 2 files changed, 56 insertions(+), 122 deletions(-) diff --git a/source/lessons/l06-python-syntax.rst b/source/lessons/l06-python-syntax.rst index 66552e9..50e8ba6 100644 --- a/source/lessons/l06-python-syntax.rst +++ b/source/lessons/l06-python-syntax.rst @@ -580,6 +580,34 @@ Docstring باید به عنوان دستور نخست درج گردد و این .. tip:: [`PEP 8 `_]: برای نام‌گذاری ثابت‌ها (Constants) تنها از حروف بزرگ و برای جداسازی کلمه‌ها نیز از ``ـ`` استفاده شود. مانند: MAX_OVERFLOW ،TOTAL و... +.. _python-none: + +NoneType +---------- + +[`None `_] یک شی آماده و بدون مقدار در پایتون است:: + + >>> n = None + + >>> type(n) + + + >>> print(n) + None + + >>> import sys + >>> sys.getsizeof(a) + 16 + + >>> n = 5 + >>> type(n) + + +این شی را می‌توان معرف مقدار هیچی یا ``null`` در پایتون نیز در نظر گرفت. یک کاربرد مهم از این شی در زمانی است که می‌خواهیم یک متغیر بدون مقدار اولیه ایجاد و مقداردهی را بر اساس شرایطی دیگر در ادامه برنامه تعریف نماییم. + +این شی کاربردهای فراوانی دارد که به مرور با آن‌ها آشنا خواهید شد. + + .. _python-operators: عملگر‌ها diff --git a/source/lessons/l08-set-and-dict-in-python.rst b/source/lessons/l08-set-and-dict-in-python.rst index ad51133..14e5bc1 100644 --- a/source/lessons/l08-set-and-dict-in-python.rst +++ b/source/lessons/l08-set-and-dict-in-python.rst @@ -354,8 +354,6 @@ * ``()items`` [`اسناد پایتون `__] تمام عضوهای شی را برمی‌گرداند - ``()values`` [`اسناد پایتون `__] تمام مقدارهای موجود در شی را بر می‌گرداند - ``()keys`` [`اسناد پایتون `__] تمام کلیدهای موجود در شی را بر می‌گرداند:: - >>> # Python 3.x - >>> d = {1:'One', 2:'Two', 3:'Three'} >>> d.items() @@ -367,48 +365,6 @@ >>> d.keys() dict_keys([1, 2, 3]) - توجه داشته باشید که در نسخه‌های 3x پایتون خروجی این متدها از نوع متفاوتی است که با استفاده از ``()type`` می‌توانید مشاهده کنید؛ این نوع ``dict_view`` نامیده می‌شود [`اسناد پایتون 3x `__]. این متدها یک کپی از داده‌های مورد نظر (عضوها یا مقدارها یا کلیدها) را بر نمی‌گردانند بلکه می‌توان گفت پنجره‌ای برای مشاهده آنچه که هست باز می‌کنند و در هر زمان که این داده‌ها تغییر کنند این خروجی‌ها نیز تغییر می‌کنند. برای مشاهده بهتر این خروجی‌ها می‌توانید آن‌ها را به نوع لیست تبدیل نمایید:: - - >>> list(d.items()) - [(1, 'One'), (2, 'Two'), (3, 'Three')] - - >>> list(d.values()) - ['One', 'Two', 'Three'] - - >>> list(d.keys()) - [1, 2, 3] - - این متدها در پایتون 2x چنین خروجی ندارند و تنها یکی کپی از داده‌ها را برمی‌گردانند. البته در نسخه 2.7 متدهای معادلی با عنوان‌های ``()viewitems`` [`اسناد پایتون `__] و ``()viewvalues`` [`اسناد پایتون `__] و ``()viewkeys`` [`اسناد پایتون `__] پورت شده است:: - - >>> # Python 2.7 - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.viewitems() - dict_items([(1, 'One'), (2, 'Two'), (3, 'Three')]) - - >>> d.viewvalues() - dict_values(['One', 'Two', 'Three']) - - >>> d.viewkeys() - dict_keys([1, 2, 3]) - - :: - - >>> # Python 2.x - - >>> d = {1:'One', 2:'Two', 3:'Three'} - - >>> d.items() - [(1, 'One'), (2, 'Two'), (3, 'Three')] - - >>> d.values() - ['One', 'Two', 'Three'] - - >>> d.keys() - [1, 2, 3] - - * ``()clear`` [`اسناد پایتون `__] - تمام عضوهای یک شی دیکشنری را حذف می‌کند:: @@ -563,20 +519,7 @@ هیچ سینتکس خاصی برای ایجاد یا بیان یک شی خالی از نوع مجموعه وجود ندارد و تنها می‌بایست از کلاس ``()set`` - بدون آرگومان - استفاده کرد. توجه داشته باشید که ``{}`` بیانگر یک شی دیکشنری خالی است و نه یک مجموعه خالی:: - >>> a = {} # Python 2.x - >>> type(a) - - - >>> b = set() - >>> type(b) - - - >>> b - set([]) - -:: - - >>> a = {} # Python 3.x + >>> a = {} >>> type(a) @@ -595,46 +538,48 @@ 5 +.. _python-set-operators: -.. rubric:: عملگرها برای مجموعه +عملگرها برای مجموعه +~~~~~~~~~~~~~~~~~~~~~~~~~~ تعدادی از عملگرها هستند که برای اشیا مجموعه تعریف خاصی پیدا می‌کنند؛ در حالی که در مورد اشیا دیگر چنین رفتاری ندارند. این عملگرها در واقع پیاده‌سازی تعریف مشخصی در مفهوم ریاضی مجموعه‌ها هستند: -* ``|`` اجتماع (Union): مانند ``A | B`` که حاصل آن مجموعه‌ای می‌باشد که تمام عضوهای مجموعه ``A`` و مجموعه ``B`` را داشته باشد و هیچ عضو اضافه دیگری نداشته باشد. +* ``|`` اجتماع (Union): مانند ``A | B`` که حاصل آن مجموعه‌ای می‌باشد که تمام عضوهای مجموعه ``A`` و مجموعه ``B`` را داشته باشد و هیچ عضو اضافه دیگری نداشته باشد:: + + >>> A = {'u', 'v', 'w', 'x', 'y', 'z'} + >>> B = {'q', 'r', 's', 't', 'u', 'v', 'w'} >>> A | B - {'w', 'y', 'q', 't', 'r', 'z', 's', 'v', 'u', 'x'} + {'y', 's', 'x', 'u', 'r', 'z', 't', 'w', 'v', 'q'} * ``&`` اشتراک (Intersection): مانند ``A & B`` که حاصل آن مجموعه‌ای می‌باشد که تنها شامل عضوهایی است که هم در مجموعه ``A`` هستند و هم در مجموعه ``B``:: >>> A & B - {'w', 'v', 'u'} + {'v', 'u', 'w'} * ``-`` تفاضل (Difference): مانند ``A - B`` که حاصل آن مجموعه‌ای می‌باشد که تنها شامل عضوهایی از مجموعه ``A`` است كه در مجموعه ``B`` نيستند:: - >>> A = {'u', 'v', 'w', 'x', 'y', 'z'} - >>> B = {'q', 'r', 's', 't', 'u', 'v', 'w',} - >>> A - B - {'z', 'y', 'x'} + {'y', 'z', 'x'} * ``^`` تفاضل متقارن (Symmetric difference): مانند ``A ^ B`` که حاصل آن مجموعه‌ای می‌باشد که برابر اجتماع ِ تفاضل ``A`` از ``B`` و تفاضل ``B`` از ``A`` می‌باشد یعنی: ``(A-B) | (B-A)``:: >>> A ^ B - {'q', 'y', 't', 'r', 'z', 's', 'x'} + {'y', 'z', 's', 'q', 'x', 'r', 't'} :: >>> (A-B) | (B-A) - {'y', 'q', 't', 'r', 'z', 'x', 's'} + {'y', 'r', 'z', 't', 's', 'x', 'q'} تفاضل متقارن را می‌توان به صورت پایین نیز تعریف کرد:: >>> (A|B) - (B&A) - {'y', 'q', 't', 'r', 'z', 's', 'x'} + {'y', 'x', 'r', 'z', 't', 's', 'q'} * ``>`` زیرمجموعه (Subset): مانند ``A < B`` که اگر مجموعه ``A`` زیرمجموعه‌ای از مجموعه ``B`` باشد مقدار ``True`` را برمی‌گرداند. در مقابل عملگر ``<`` قرار دارد که برای مثال در عبارت ``A > B`` اگر مجموعه ``A`` یک Superset برای مجموعه ``B`` باشد مقدار ``True`` را برمی‌گرداند:: @@ -672,7 +617,11 @@ >>> A is C True -.. rubric:: برخی از متدهای کاربردی یک شی مجموعه + +.. _python-set-methods: + +برخی از متدهای کاربردی یک شی مجموعه +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``()union`` [`اسناد پایتون `__] - تعدادی شی مجموعه را دریافت می‌کند و یک مجموعه جدید که برابر اجتماع شی مورد نظر با آن‌ها است را برمی‌گرداند:: @@ -745,25 +694,12 @@ KeyError: 'pop from an empty set' -.. rubric:: frozenset - -همانطور که پیش از این بیان شد مجموعه یک شی «تغییر پذیر» است با عضوهای «تغییر ناپذیر» و به دلیل همین تغییر پذیری است که می‌توانیم به سادگی توسط متدها عضوی به آن افزوده یا حذف نماییم. **”frozenset“** یک نوع جدید مجموعه است. همانگونه که می‌توانیم یک شی تاپل را معادل یک شی لیست تغییر ناپذیر تصویر کنیم؛ frozenset را نیز می‌توان **یک شی مجموعه تغییر ناپذیر** تصور کرد. نوع ``frozenset`` همان نوع ``set`` است، با تمام ویژگی‌های آن به غیر از تغییر پذیری که با استفاده از کلاس ``()frozenset`` ایجاد می‌گردد: - -*نسخه‌های 2x:* - -:: - - >>> L = [1, 2, 3] - - >>> A = frozenset(L) +.. _python-frozenset: - >>> type(A) - +frozenset +~~~~~~~~~~~~~ - >>> A - frozenset([1, 2, 3]) - -*نسخه‌های 3x:* +همانطور که پیش از این بیان شد مجموعه یک شی «تغییر پذیر» است با عضوهای «تغییر ناپذیر» و به دلیل همین تغییر پذیری است که می‌توانیم به سادگی توسط متدهایش، عضوی به آن افزوده یا حذف نماییم. **”frozenset“** یک نوع جدید مجموعه است. همانگونه که می‌توانیم یک شی تاپل را معادل یک شی لیست تغییر ناپذیر تصویر کنیم؛ frozenset را نیز می‌توان **یک شی مجموعه تغییر ناپذیر** تصور کرد. نوع ``frozenset`` همان نوع ``set`` است، با تمام ویژگی‌های آن به غیر از تغییر پذیری که با استفاده از کلاس ``()frozenset`` ایجاد می‌گردد: :: @@ -783,34 +719,10 @@ ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union'] -NoneType ----------- - -این نوع شی فاقد مقدار است و با انتساب ثابت ``None`` [`اسناد پایتون `__] به یک نام ایجاد می‌گردد:: - - >>> n = None - - >>> type(n) - - - >>> print(n) - None - - >>> import sys - >>> sys.getsizeof(a) - 16 - - >>> n = 5 - >>> type(n) - - -``None`` در پایتون 3x جزو کلمه‌های کلیدی (keywords) تعریف شده است. - - دسته‌بندی ----------- -در این بخش به دسته‌بندی انواع شی بر اساس برخی از تعریف‌های پایتون پرداخته شده است. +اکنون با انواع داده و نیز ساختمان‌های داده متداول در پایتون آشنا شده‌اید. در این بخش به منظور جمع‌بندی، به دسته‌بندی این اشیا خواهیم پرداخت: * انواع عددی (Numeric Types): @@ -819,7 +731,6 @@ NoneType :linenos: - int - - long (2.x) - float - complex - Decimal @@ -832,9 +743,8 @@ NoneType :linenos: - str - - unicode (2.x) - - bytes (3.x) - - bytearray (3.x/2.6+) + - bytes + - bytearray - tuple - list @@ -844,15 +754,13 @@ NoneType :linenos: - int - - long (2.x) - float - complex - Decimal - Fraction - bool - str - - unicode (2.x) - - bytes (3.x) + - bytes - tuple - frozenset @@ -862,7 +770,7 @@ NoneType .. code-block:: html :linenos: - - bytearray (3.x/2.6+) + - bytearray - list - dict - set @@ -889,10 +797,8 @@ NoneType :linenos: - zip - - dict_views - NoneType -*در درس‌های بعد نیز با انواع آماده (Built-in) دیگری آشنا خواهیم شد.* | From 059b64adf9da6d82c08f825375946db39b679952 Mon Sep 17 00:00:00 2001 From: Saeid Darvish Date: Thu, 20 Apr 2023 20:09:42 +0330 Subject: [PATCH 5/5] edited l08 (part 1 & 2) --- .../pages/08-python-built-in-data-types-3.jpg | Bin 0 -> 130374 bytes source/_static/sitemap-index.xml | 10 +++++ .../lessons/l07-numeric-types-in-python.rst | 2 +- source/lessons/l07-string-in-python.rst | 2 +- .../lessons/l08-list-and-tuple-in-python.rst | 40 ++++++++++-------- source/lessons/l08-set-and-dict-in-python.rst | 12 +++--- source/lessons/l09.rst | 4 +- source/lessons/l11.rst | 12 +++--- source/lessons/l12.rst | 8 ++-- source/lessons/l13.rst | 4 +- source/lessons/l16.rst | 10 ++--- source/lessons/l18.rst | 2 +- source/lessons/l19.rst | 2 +- source/lessons/l21.rst | 2 +- source/lessons/l22.rst | 2 +- source/lessons/l23.rst | 2 +- source/log.rst | 13 +++++- 17 files changed, 76 insertions(+), 51 deletions(-) create mode 100644 source/_static/pages/08-python-built-in-data-types-3.jpg diff --git a/source/_static/pages/08-python-built-in-data-types-3.jpg b/source/_static/pages/08-python-built-in-data-types-3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7178bafc181046fac57417215eb66ddbe33bb67c GIT binary patch literal 130374 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

5E%;jZNabnPs!J0=va&`RT?1(WY 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 k=WykZ>U#eKKs)P+{+8Qvd(} literal 0 HcmV?d00001 diff --git a/source/_static/sitemap-index.xml b/source/_static/sitemap-index.xml index 1e45b37..ce5a31e 100644 --- a/source/_static/sitemap-index.xml +++ b/source/_static/sitemap-index.xml @@ -94,6 +94,16 @@ 2021-03-17T17:10:25+00:00 0.80 + + https://python.coderz.ir/lessons/l08-list-and-tuple-in-python.html + 2023-03-17T17:10:25+00:00 + 0.80 + + + https://python.coderz.ir/lessons/l08-set-and-dict-in-python.html + 2023-03-17T17:10:25+00:00 + 0.80 + https://python.coderz.ir/lessons/l09.html 2021-03-17T17:10:25+00:00 diff --git a/source/lessons/l07-numeric-types-in-python.rst b/source/lessons/l07-numeric-types-in-python.rst index 5ed21cc..2c77cf1 100644 --- a/source/lessons/l07-numeric-types-in-python.rst +++ b/source/lessons/l07-numeric-types-in-python.rst @@ -519,7 +519,7 @@ f = Decimal("NaN") * از آنجا که نوع ممیز شناور دقیق نیست؛ این اعداد را حتما به صورت رشته به ``Decimal`` ارسال نمایید (سطر دوم). -* اعداد را می‌توان به صورت یک شی تاپل (Tuple) - ساختاری مشابه: (... ,Ο, Ο, Ο) - ارسال کرد (سطر چهارم). شیوه نماد علمی را به یاد بیاورید؛ تاپل مورد نظر باید ساختاری مشابه الگو ``(sign, digits, exponent)`` داشته باشد که در آن sign مثبت بودن (توسط عدد صفر) یا منفی بودن (توسط عدد یک) را مشخص می‌کند، digits خود تاپلی است که رقم‌های دخیل را بیان می‌کند و exponent نیز بیانگر همان توان است. +* اعداد را می‌توان به صورت یک شی توپِل (Tuple) - ساختاری مشابه: (... ,Ο, Ο, Ο) - ارسال کرد (سطر چهارم). شیوه نماد علمی را به یاد بیاورید؛ توپِل مورد نظر باید ساختاری مشابه الگو ``(sign, digits, exponent)`` داشته باشد که در آن sign مثبت بودن (توسط عدد صفر) یا منفی بودن (توسط عدد یک) را مشخص می‌کند، digits خود توپِلی است که رقم‌های دخیل را بیان می‌کند و exponent نیز بیانگر همان توان است. میزان دقت (Precision) و عمل گرد کردن (Rounding) اعداد از نوع دسیمال با استفاده از یک شی ``Context`` قابل کنترل است؛ این شی یک سری اطلاعات پیکربندی را در اختیار اشیا دسیمال قرار می‌دهد که برای دسترسی به آن باید از تابع ``()getcontext`` [`اسناد پایتون `__] درون ماژول ``decimal`` استفاده کرد. تابع ``()getcontext`` شی ``Context`` اشیا دسیمال جاری برنامه را برمی‌گرداند:: diff --git a/source/lessons/l07-string-in-python.rst b/source/lessons/l07-string-in-python.rst index ef9ebb2..fd223e6 100644 --- a/source/lessons/l07-string-in-python.rst +++ b/source/lessons/l07-string-in-python.rst @@ -119,7 +119,7 @@ رشته به عنوان دنباله‌ (Sequence) ---------------------------------- -برخی از انواع شی پایتون به مانند رشته، تاپل (tuple)، لیست (list) و... با عنوان **دنباله** (Sequence) نیز شناخته می‌شوند. دنباله ویژگی‌هایی دارد که در اینجا به کمک نوع رشته بررسی خواهیم کرد. رشته در واقع یک **دنباله** از کاراکترهاست در نتیجه می‌توان هر یک از اعضای این دنباله را با استفاده از اندیس (Index) موقعیت آن، دستیابی نمود؛ اندیس اعضا از سمت چپ با عدد صفر شروع و به سمت راست یک واحد یک واحد افزایش می‌یابد. به عنوان نمونه برای شی ``'Python Strings'`` می‌توانیم شمای اندیس‌گذاری را به صورت پایین در نظر بگیریم:: +برخی از انواع شی پایتون به مانند رشته، توپِل (tuple)، لیست (list) و... با عنوان **دنباله** (Sequence) نیز شناخته می‌شوند. دنباله ویژگی‌هایی دارد که در اینجا به کمک نوع رشته بررسی خواهیم کرد. رشته در واقع یک **دنباله** از کاراکترهاست در نتیجه می‌توان هر یک از اعضای این دنباله را با استفاده از اندیس (Index) موقعیت آن، دستیابی نمود؛ اندیس اعضا از سمت چپ با عدد صفر شروع و به سمت راست یک واحد یک واحد افزایش می‌یابد. به عنوان نمونه برای شی ``'Python Strings'`` می‌توانیم شمای اندیس‌گذاری را به صورت پایین در نظر بگیریم:: P y t h o n S t r i n g s - - - - - - - - - - - - - - diff --git a/source/lessons/l08-list-and-tuple-in-python.rst b/source/lessons/l08-list-and-tuple-in-python.rst index 9d9d191..de66a2c 100644 --- a/source/lessons/l08-list-and-tuple-in-python.rst +++ b/source/lessons/l08-list-and-tuple-in-python.rst @@ -10,18 +10,18 @@ درس ۰۸: ساختمان‌های داده در پایتون: list و tuple ==================================================================================== -.. figure:: /_static/pages/08-python-built-in-data-types-2.jpg +.. figure:: /_static/pages/08-python-built-in-data-types-3.jpg :align: center :alt: درس ۰۸: ساختمان‌های داده در پایتون: tuple و list :class: page-image - Photo by `Natalia Y `__ + Photo by `Maria Orlova `__ -از درس هفتم با انواع داده از پیش آماده در پایتون آشنا شده‌ایم و در این درس به ساختمان‌های داده در پایتون خواهیم پرداخت. ساختمان‌های داده یا Data Structures به اشیایی گفته می‌شود که برای نگهداری از یک مجموعه داده طراحی شده‌اند و هر یک دارای ویژگی منحصربه‌فرد خود است. برای مثال قابل تغییر بودن، امکان حفظ ترتیب اعضا، امکان نگهداری داده‌های تکراری یا تنها اجبار به نگهداری داده‌های یکتا که هر یک مناسب وضعیت خاصی در برنامه‌نویسی هستند. این درس به بررسی چهار ساختمان داده متداول در پایتون خواهد پرداخت: لیست (list)، تاپِل (tuple)، مجموعه (set) و دیکشنری (dict) +از درس هفتم با انواع داده پایه در پایتون آشنا شده‌ایم و در این درس به بررسی انواع داده دیگری خواهیم پرداخت که در زبان‌های برنامه‌نویسی عموما با عنوان ساختمان‌های داده بیان می‌شوند. ساختمان‌های داده یا Data Structures به اشیایی گفته می‌شود که برای نگهداری از یک مجموعه داده طراحی شده‌اند و هر یک دارای ویژگی منحصربه‌فرد خود است. برای مثال قابل تغییر بودن، امکان حفظ ترتیب اعضا، امکان نگهداری داده‌های تکراری یا تنها اجبار به نگهداری داده‌های یکتا که هر یک مناسب وضعیت خاصی در برنامه‌نویسی هستند. این درس به بررسی چهار ساختمان داده متداول در پایتون خواهد پرداخت: لیست (list)، توپِل (tuple)، مجموعه (set) و دیکشنری (dict) -به منظور جلوگیری از طولانی شدن متن درس و همینطور سادگی در مطالعه، محتوا این درس در قالب دو بخش ارایه می‌شود که بخش نخست تنها به شرح لیست (list) و تاپِل (tuple) خواهد پرداخت. +به منظور جلوگیری از طولانی شدن متن درس و همینطور سادگی در مطالعه، محتوا این درس در قالب دو بخش ارایه می‌شود که بخش نخست تنها به شرح لیست (list) و توپِل (tuple) خواهد پرداخت. @@ -40,7 +40,7 @@ لیست ------ -نوع «**لیست**» (List) انعطاف‌ پذیرترین نوع آماده در پایتون می‌باشد. این نوع همانند رشته یک «**دنباله**» (Sequence) بوده ولی برخلاف آن یک نوع «**تغییر پذیر**» (Mutable) است. شی لیست با استفاده از کروشه ``[ ]`` ایجاد می‌گردد و ترتیب اعضا را حفظ و می‌تواند عضوهایی - **از هر نوع** - داشته باشد که توسط کاما ``,`` از یکدیگر جدا می‌شوند؛ نوع لیست در واقع محلی برای نگهداری اشیا گوناگون و تغییرپذیر است:: +نوع «**لیست**» (List) یک نوع بسیار انعطاف‌پذیر در پایتون می‌باشد. این نوع همانند رشته یک «**دنباله**» (Sequence) بوده ولی برخلاف آن یک نوع «**تغییر پذیر**» (Mutable) است. شی لیست با استفاده از کروشه ``[ ]`` ایجاد می‌گردد و ترتیب اعضا را حفظ و می‌تواند عضوهایی - **از هر نوع** - داشته باشد که توسط کاما ``,`` از یکدیگر جدا می‌شوند؛ نوع لیست در واقع محلی برای نگهداری اشیا گوناگون و تغییرپذیر است:: >>> L = [1, 2, 3] >>> type(L) @@ -201,7 +201,11 @@ File "", line 1, in NameError: name 'a' is not defined -.. rubric:: انتساب چندگانه + +.. _python-unpacking: + +انتساب چندگانه +~~~~~~~~~~~~~~~~~~~~ می‌توان یک شی لیست - یا در کل یک شی دنباله - را به تعدادی نام انتساب داد و متغیرهای جداگانه‌ای ایجاد نمود؛ این عمل **Unpacking** خوانده می‌شود. در این شرایط مفسر پایتون هر عضو دنباله را با حفظ ترتیب به یکی از نام‌ها انتساب می‌دهد که در حالت عادی می‌بایست تعداد نام‌ها با عضوهای دنباله برابر باشد:: @@ -747,10 +751,10 @@ -تاپل +توپِل ------ -نوع «**تاپِل**» (Tuple) همانند نوع ``list`` است ولی با این تفاوت که تغییر پذیر **نیست** و عضوهای آن درون پرانتز ``()`` قرار داده می‌شوند:: +نوع «**توپِل**» (Tuple) همانند نوع ``list`` است تنها با این تفاوت که تغییرپذیر **نیست** (بنابراین به نسبت مقدار حافظه کمتری مصرف می‌کند) و عضوهای آن درون پرانتز ``()`` قرار داده می‌شوند:: >>> t = (1, 2, 3) >>> type(t) @@ -771,7 +775,7 @@ >>> t () -در انتهای شی تاپل تک عضوی می‌بایست یک نماد کاما قرار داد؛ به مانند: ``(,1)``. از آنجا که از پرانتز در عبارت‌ها نیز استفاده می‌شود؛ با این کار مفسر پایتون یک شی تاپل را از عبارت تشخیص می دهد:: +در انتهای شی توپِل تک عضوی می‌بایست یک نماد کاما قرار داد؛ به مانند: ``(,1)``. از آنجا که از پرانتز در عبارت‌ها نیز استفاده می‌شود؛ با این کار مفسر پایتون یک شی توپِل را از عبارت تشخیص می دهد:: >>> (4 + 1) @@ -792,7 +796,7 @@ -برای ایجاد شی تاپل حتی می‌توان از گذاردن پرانتز صرف نظر کرد و تنها اشیا (یا عبارت‌ها) را با کاما از یکدیگر جدا نمود:: +برای ایجاد شی توپِل حتی می‌توان از گذاردن پرانتز صرف نظر کرد و تنها اشیا (یا عبارت‌ها) را با کاما از یکدیگر جدا نمود:: >>> 5, (5,) @@ -816,10 +820,10 @@ .. note:: - نوع تاپل به دلیل تغییر ناپذیر بودن، نسبت به نوع لیست در مصرف حافظه بهینه‌تر می‌باشد؛ بنابراین بهتر است در مواقعی که نیاز به تغییر خاصی در داده‌ها نیست از این نوع استفاده شود. همچنین در مواقعی که نباید داده‌ها تغییر کنند، استفاده از شی تاپل به جای لیست می‌تواند از آن‌ها در برابر تغییر محافظت کند. + نوع توپِل به دلیل تغییر ناپذیر بودن، نسبت به نوع لیست در مصرف حافظه بهینه‌تر می‌باشد؛ بنابراین بهتر است در مواقعی که نیاز به تغییر خاصی در داده‌ها نیست از این نوع استفاده شود. همچنین در مواقعی که نباید داده‌ها تغییر کنند، استفاده از شی توپِل به جای لیست می‌تواند از آن‌ها در برابر تغییر محافظت کند. -به دلیل شباهت‌های بسیار شی تاپل به شی لیست از ارایه توضیحات تکراری اجتناب کرده و تنها به ذکر چند مثال در ارتباط با نوع تاپل می‌پردازیم:: +به دلیل شباهت‌های بسیار شی توپِل به شی لیست از ارایه توضیحات تکراری اجتناب کرده و تنها به ذکر چند مثال در ارتباط با نوع توپِل می‌پردازیم:: >>> ('a', 'b', 'c') + (1 , 2, 3) ('a', 'b', 'c', 1, 2, 3) @@ -890,7 +894,7 @@ >>> len(t[2]) 3 -به دلیل ساختار ارجاعی بین اشیا در پایتون که توسط تصاویر بخش لیست نیز نمایش داده شد؛ اشیا تغییر پذیر درون شی تاپل، ویژگی‌های خود را داشته و همچنان تغییر پذیر خواهند بود:: +به دلیل ساختار ارجاعی بین اشیا در پایتون که توسط تصاویر بخش لیست نیز نمایش داده شد؛ اشیا تغییر پذیر درون شی توپِل، ویژگی‌های خود را داشته و همچنان تغییر پذیر خواهند بود:: >>> t = ('p', 'y', [1, 2, 3], 5) @@ -952,7 +956,7 @@ *حتما متوجه شده‌اید که عضوهای دنباله تنها با نوع لیست به نام نشانه‌گذاری شده انتساب داده می‌شود.* -در هنگام انتساب متغیر تاپل به موضوع کپی نشدن اشیا تغییر پذیر توجه داشته باشید و در صورت نیاز از ماژول ``copy`` استفاده نمایید:: +در هنگام انتساب متغیر توپِل به موضوع کپی نشدن اشیا تغییر پذیر توجه داشته باشید و در صورت نیاز از ماژول ``copy`` استفاده نمایید:: >>> t1 = ('p', 'y', [1, 2, 3], 5) @@ -981,7 +985,7 @@ -همانند شی لیست؛ شی تاپل نیز به دو متد ``()index`` و ``()count`` دسترسی دارد - این موضوع با استفاده از تابع ``()dir`` قابل بررسی است:: +همانند شی لیست؛ شی توپِل نیز به دو متد ``()index`` و ``()count`` دسترسی دارد - این موضوع با استفاده از تابع ``()dir`` قابل بررسی است:: >>> t = ('s', 'b', 'c', 'a', 's', 'b') @@ -1024,7 +1028,7 @@ (END) -هر زمان که نیاز به اِعمال تغییر در شی تاپل باشد؛ می‌توان شی مورد نظر را به صورت موقت به یک شی لیست تبدیل کرد. در این حالت می‌توان از ویژگی و متدهای شی لیست بهره برد و تغییرات دلخواه را اعمال کرد و در نهایت با یک تبدیل نوع دیگر دوباره به شی تاپل بازگشت. برای این منظور می‌توان با استفاده از کلاس ``()list`` یک دنباله - در اینجا یک شی تاپل - را به شی لیست تبدیل کرد و در طرف دیگر توسط کلاس ``()tuple`` نیز یک دنباله - در اینجا یک شی لیست - را به شی تاپل تبدیل نمود:: +هر زمان که نیاز به اِعمال تغییر در شی توپِل باشد؛ می‌توان شی مورد نظر را به صورت موقت به یک شی لیست تبدیل کرد. در این حالت می‌توان از ویژگی و متدهای شی لیست بهره برد و تغییرات دلخواه را اعمال کرد و در نهایت با یک تبدیل نوع دیگر دوباره به شی توپِل بازگشت. برای این منظور می‌توان با استفاده از کلاس ``()list`` یک دنباله - در اینجا یک شی توپِل - را به شی لیست تبدیل کرد و در طرف دیگر توسط کلاس ``()tuple`` نیز یک دنباله - در اینجا یک شی لیست - را به شی توپِل تبدیل نمود:: >>> t = (1, 2, 3) >>> type(t) @@ -1045,7 +1049,7 @@ ('python', 1, 2, 3) -البته در مواقعی که می‌خواهید عضوهای درون یک شی تاپل را مرتب (Sort) کنید، نیازی به تبدیل نوع لیست نمی‌باشد و می‌توانید از تابع ``()sorted`` استفاده نمایید؛ این تابع مطابق آنچه که پیش از این معرفی شد یک شی تاپل را می‌گیرد و یک شی لیست با همان عضوها اما مرتب شده را برمی‌گرداند:: +البته در مواقعی که می‌خواهید عضوهای درون یک شی توپِل را مرتب (Sort) کنید، نیازی به تبدیل نوع لیست نمی‌باشد و می‌توانید از تابع ``()sorted`` استفاده نمایید؛ این تابع مطابق آنچه که پیش از این معرفی شد یک شی توپِل را می‌گیرد و یک شی لیست با همان عضوها اما مرتب شده را برمی‌گرداند:: >>> t = ('a', 'D', 'c', 'B', 'e', 'f', 'G', 'h') @@ -1053,7 +1057,7 @@ ['h', 'G', 'f', 'e', 'D', 'c', 'B', 'a'] -کلاس ``()tuple`` بدون آرگومان یک شی تاپل خالی را ایجاد می‌کند:: +کلاس ``()tuple`` بدون آرگومان یک شی توپِل خالی را ایجاد می‌کند:: >>> t = tuple() >>> t diff --git a/source/lessons/l08-set-and-dict-in-python.rst b/source/lessons/l08-set-and-dict-in-python.rst index 14e5bc1..74b50d4 100644 --- a/source/lessons/l08-set-and-dict-in-python.rst +++ b/source/lessons/l08-set-and-dict-in-python.rst @@ -18,10 +18,10 @@ Photo by `Natalia Y `__ + +از درس هفتم با انواع داده پایه در پایتون آشنا شده‌ایم و در این درس به بررسی انواع داده دیگری خواهیم پرداخت که در زبان‌های برنامه‌نویسی عموما با عنوان ساختمان‌های داده بیان می‌شوند. ساختمان‌های داده یا Data Structures به اشیایی گفته می‌شود که برای نگهداری از یک مجموعه داده طراحی شده‌اند و هر یک دارای ویژگی منحصربه‌فرد خود است. برای مثال قابل تغییر بودن، امکان حفظ ترتیب اعضا، امکان نگهداری داده‌های تکراری یا تنها اجبار به نگهداری داده‌های یکتا که هر یک مناسب وضعیت خاصی در برنامه‌نویسی هستند. این درس به بررسی چهار ساختمان داده متداول در پایتون خواهد پرداخت: لیست (list)، توپِل (tuple)، مجموعه (set) و دیکشنری (dict) -از درس هفتم با انواع داده از پیش آماده در پایتون آشنا شده‌ایم و در این درس به ساختمان‌های داده در پایتون خواهیم پرداخت. ساختمان‌های داده یا Data Structures به اشیایی گفته می‌شود که برای نگهداری از یک مجموعه داده طراحی شده‌اند و هر یک دارای ویژگی منحصربه‌فرد خود است. برای مثال قابل تغییر بودن، امکان حفظ ترتیب اعضا، امکان نگهداری داده‌های تکراری یا تنها اجبار به نگهداری داده‌های یکتا که هر یک مناسب وضعیت خاصی در برنامه‌نویسی هستند. این درس به بررسی چهار ساختمان داده متداول در پایتون خواهد پرداخت: لیست (list)، تاپِل (tuple)، مجموعه (set) و دیکشنری (dict) - -این بخش در ادامه شرح «لیست» و «تاپل» به شرح دو نوع دیگر از ساختمان‌های داده در پایتون می‌پردازد: «مجموعه» و «دیکشنری» +این بخش در ادامه شرح «لیست» و «توپِل» به شرح دو نوع دیگر از ساختمان‌های داده در پایتون می‌پردازد: «مجموعه» و «دیکشنری» @@ -287,7 +287,7 @@ برای تبدیل دیگر اشیا به نوع دیکشنری یا در کل ایجاد شی دیکشنری از کلاس ``()dict`` [`اسناد پایتون `__] استفاده می‌شود. -برای تبدیل اشیا دنباله به مانند لیست و تاپل به دیکشنری می‌بایست از ساختار تودرتو استفاده کرد، به گونه‌ای که هر عضو این ساختمان‌ها خود شامل دو عضو باشد:: +برای تبدیل اشیا دنباله به مانند لیست و توپِل به دیکشنری می‌بایست از ساختار تودرتو استفاده کرد، به گونه‌ای که هر عضو این ساختمان‌ها خود شامل دو عضو باشد:: >>> t = ('one', 'two', 'three') >>> type(t) @@ -427,7 +427,7 @@ >>> d {'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'} - متد مشابه دیگری نیز با نام ``()popitem`` [`اسناد پایتون `__] - که بدون آرگومان است - در دسترس می‌باشد؛ این متد در هر فراخوانی یک عضو از شی مورد نظر را به صورت دلخواه حذف و به شکل تاپل (key, value) برمی‌گرداند و چنانچه دیکشنری خالی باشد یک خطا ``KeyError`` گزارش می‌دهد:: + متد مشابه دیگری نیز با نام ``()popitem`` [`اسناد پایتون `__] - که بدون آرگومان است - در دسترس می‌باشد؛ این متد در هر فراخوانی یک عضو از شی مورد نظر را به صورت دلخواه حذف و به شکل توپِل (key, value) برمی‌گرداند و چنانچه دیکشنری خالی باشد یک خطا ``KeyError`` گزارش می‌دهد:: >>> d = {1:'One', 2:'Two', 3:'Three'} @@ -699,7 +699,7 @@ frozenset ~~~~~~~~~~~~~ -همانطور که پیش از این بیان شد مجموعه یک شی «تغییر پذیر» است با عضوهای «تغییر ناپذیر» و به دلیل همین تغییر پذیری است که می‌توانیم به سادگی توسط متدهایش، عضوی به آن افزوده یا حذف نماییم. **”frozenset“** یک نوع جدید مجموعه است. همانگونه که می‌توانیم یک شی تاپل را معادل یک شی لیست تغییر ناپذیر تصویر کنیم؛ frozenset را نیز می‌توان **یک شی مجموعه تغییر ناپذیر** تصور کرد. نوع ``frozenset`` همان نوع ``set`` است، با تمام ویژگی‌های آن به غیر از تغییر پذیری که با استفاده از کلاس ``()frozenset`` ایجاد می‌گردد: +همانطور که پیش از این بیان شد مجموعه یک شی «تغییر پذیر» است با عضوهای «تغییر ناپذیر» و به دلیل همین تغییر پذیری است که می‌توانیم به سادگی توسط متدهایش، عضوی به آن افزوده یا حذف نماییم. **”frozenset“** یک نوع جدید مجموعه است. همانگونه که می‌توانیم یک شی توپِل را معادل یک شی لیست تغییر ناپذیر تصویر کنیم؛ frozenset را نیز می‌توان **یک شی مجموعه تغییر ناپذیر** تصور کرد. نوع ``frozenset`` همان نوع ``set`` است، با تمام ویژگی‌های آن به غیر از تغییر پذیری که با استفاده از کلاس ``()frozenset`` ایجاد می‌گردد: :: diff --git a/source/lessons/l09.rst b/source/lessons/l09.rst index 56c87be..4a95ae4 100644 --- a/source/lessons/l09.rst +++ b/source/lessons/l09.rst @@ -508,7 +508,7 @@ 5 6 >>> -*در نمونه کد بالا، متغیر both در هر مرتبه تکرار به یک شی تاپل اشاره دارد.* +*در نمونه کد بالا، متغیر both در هر مرتبه تکرار به یک شی توپِل اشاره دارد.* :: @@ -884,7 +884,7 @@ در این بخش قصد داریم با مفهوم iterator (تکرارکننده) در پایتون آشنا شویم. برای این منظور بهتر است ابتدا مفهوم iterable (تکرارپذیر) را بدانیم. -تمام انواع دنباله یک iterable هستند؛ در واقع به اشیایی با این قابلیت که بتوان در هر لحظه یک عضو درون آن را دستیابی نمود iterable گفته می‌شود. اکثر انواع آماده شی که در پایتون می‌شناسیم یک iterable است؛ انواع شی رشته، لیست، تاپل، دیکشنری، range ،zip (یا xrange) یا یک شی فایل (file) و هر شی از کلاسی که خودتان به همراه متد‌های ویژه ``()__iter__`` یا ``()__getitem__`` تعریف نمایید یک iterable هستند. +تمام انواع دنباله یک iterable هستند؛ در واقع به اشیایی با این قابلیت که بتوان در هر لحظه یک عضو درون آن را دستیابی نمود iterable گفته می‌شود. اکثر انواع آماده شی که در پایتون می‌شناسیم یک iterable است؛ انواع شی رشته، لیست، توپِل، دیکشنری، range ،zip (یا xrange) یا یک شی فایل (file) و هر شی از کلاسی که خودتان به همراه متد‌های ویژه ``()__iter__`` یا ``()__getitem__`` تعریف نمایید یک iterable هستند. شی iterator با استفاده از تابع آماده ``()iter`` [`اسناد پایتون `__] ایجاد می‌شود؛ این تابع یک شی iterable را به عنوان آرگومان دریافت می‌کند و آن را در قالب یک شی iterator بر می‌گرداند:: diff --git a/source/lessons/l11.rst b/source/lessons/l11.rst index 3e04993..bf923ed 100644 --- a/source/lessons/l11.rst +++ b/source/lessons/l11.rst @@ -508,7 +508,7 @@ os.path -* ``(os.path.split(path``: مسیر path دریافتی را به یک تاپل (dirname, basename) تجزیه می‌کند که در آن **basename** آخرین بخش از مسیر path و **dirname** نیز هر آنچه قبل از basename باشد، خواهند بود [`اسناد پایتون `__]:: +* ``(os.path.split(path``: مسیر path دریافتی را به یک توپِل (dirname, basename) تجزیه می‌کند که در آن **basename** آخرین بخش از مسیر path و **dirname** نیز هر آنچه قبل از basename باشد، خواهند بود [`اسناد پایتون `__]:: >>> import os.path @@ -528,7 +528,7 @@ os.path >>> -* ``(os.path.basename(path``: مقداری برابر با **بخش دوم** از تاپل خروجی تابع ``(os.path.split(path`` را برمی‌گرداند [`اسناد پایتون `__]:: +* ``(os.path.basename(path``: مقداری برابر با **بخش دوم** از توپِل خروجی تابع ``(os.path.split(path`` را برمی‌گرداند [`اسناد پایتون `__]:: >>> import os.path @@ -548,7 +548,7 @@ os.path >>> -* ``(os.path.dirname(path``: مقداری برابر با **بخش یکم** از تاپل خروجی تابع ``(os.path.split(path`` را برمی‌گرداند [`اسناد پایتون `__]:: +* ``(os.path.dirname(path``: مقداری برابر با **بخش یکم** از توپِل خروجی تابع ``(os.path.split(path`` را برمی‌گرداند [`اسناد پایتون `__]:: >>> import os.path >>> @@ -568,7 +568,7 @@ os.path -* ``(os.path.splitext(path``: مشابه تابع ``(os.path.split(path`` است با این تفاوت که پسوند را از path جدا کرده و نتیجه را به شکل تاپل بر می‌گرداند [`اسناد پایتون `__]:: +* ``(os.path.splitext(path``: مشابه تابع ``(os.path.split(path`` است با این تفاوت که پسوند را از path جدا کرده و نتیجه را به شکل توپِل بر می‌گرداند [`اسناد پایتون `__]:: >>> import os.path >>> @@ -613,7 +613,7 @@ os.path >>> os.path.join(os.sep, 'one', 'two', 'three') '\\one\\two\\three' - همچنین برای ایجاد چندین مسیر به صورت همزمان، می‌توان اجزای هر مسیر را به صورت یک تاپل (یا لیست) درون یک لیست قرار داد و سپس با استفاده از حلقه ``for``، اجزای هر مسیر را جداگانه به تابع ``join`` ارسال نمود. البته باید توجه داشت که می‌بایست پارامتر مشخص شده در تعریف تابع ``join`` با یک ستاره مشخص شده باشد؛ در این حالت اجزای درون یک تاپل (یا لیست) به صورت پارامترهای جدا تابع در نظر گرفته می‌شوند، چیزی مانند نمونه کد بالا - در درس تابع دوباره به این شیوه ارسال پارامتر اشاره خواهد شد - به نمونه کد پایین توجه نمایید:: + همچنین برای ایجاد چندین مسیر به صورت همزمان، می‌توان اجزای هر مسیر را به صورت یک توپِل (یا لیست) درون یک لیست قرار داد و سپس با استفاده از حلقه ``for``، اجزای هر مسیر را جداگانه به تابع ``join`` ارسال نمود. البته باید توجه داشت که می‌بایست پارامتر مشخص شده در تعریف تابع ``join`` با یک ستاره مشخص شده باشد؛ در این حالت اجزای درون یک توپِل (یا لیست) به صورت پارامترهای جدا تابع در نظر گرفته می‌شوند، چیزی مانند نمونه کد بالا - در درس تابع دوباره به این شیوه ارسال پارامتر اشاره خواهد شد - به نمونه کد پایین توجه نمایید:: >>> import os @@ -629,7 +629,7 @@ os.path >>> .. note:: - هر مسیر می‌بایست دقیقا شامل یک کاراکتر جدا کننده دایرکتوری (``os.sep``) باشد در غیر این صورت اجزا فقط از آخرین نمونه به بعد در نظر گرفته می‌شوند. این اتفاق در تاپل سوم ``('one', 'two', '/three', 'four/')`` از نمونه کد بالا رخ داده است. + هر مسیر می‌بایست دقیقا شامل یک کاراکتر جدا کننده دایرکتوری (``os.sep``) باشد در غیر این صورت اجزا فقط از آخرین نمونه به بعد در نظر گرفته می‌شوند. این اتفاق در توپِل سوم ``('one', 'two', '/three', 'four/')`` از نمونه کد بالا رخ داده است. * ``(os.path.expanduser(path``: این تابع تنها یک پارامتر با ترکیب ``user~`` می‌پذیرد و کاراکتر ``~`` را به مسیر دایرکتوری کاربر user در سیستم عامل تبدیل می‌کند [`اسناد پایتون `__]:: diff --git a/source/lessons/l12.rst b/source/lessons/l12.rst index 7f6f189..5ead167 100644 --- a/source/lessons/l12.rst +++ b/source/lessons/l12.rst @@ -360,7 +360,7 @@ این دو از شیوه‌‌های مرسوم در زبان‌های برنامه‌نویسی هستند ولی ارسال پارامتر به صورت خاص در زبان برنامه‌نویسی پایتون چگونه است؟ در پایتون هر چیزی یک شی است و در نتیجه ارسال آرگومان‌ها در هر شرایطی به صورت **”by reference“** انجام می‌پذیرد. -و اگر سوال شود که علت تفاوت رفتار در دو مثال قبل چیست؟ باید بدانیم که علت به ماهیت اشیای آرگومان‌های ارسالی مربوط است. ارسال اشیای تغییرناپذیر (Immutable) به مانند انواع بولین، اعداد، رشته و تاپل به تابع، باعث بروز رفتاری مشابه با شیوه by value می‌شود ولی در مورد ارسال اشیای تغییرپذیر (Mutable) به مانند انواع لیست، دیکشنری و مجموعه اینگونه نخواهد بود. به تصاویر پایین توجه نمایید: +و اگر سوال شود که علت تفاوت رفتار در دو مثال قبل چیست؟ باید بدانیم که علت به ماهیت اشیای آرگومان‌های ارسالی مربوط است. ارسال اشیای تغییرناپذیر (Immutable) به مانند انواع بولین، اعداد، رشته و توپِل به تابع، باعث بروز رفتاری مشابه با شیوه by value می‌شود ولی در مورد ارسال اشیای تغییرپذیر (Mutable) به مانند انواع لیست، دیکشنری و مجموعه اینگونه نخواهد بود. به تصاویر پایین توجه نمایید: .. image:: /_static/l12-python-passing-arguments-01.png :align: center @@ -416,7 +416,7 @@ >>> Y [3, 4] -توجه داشته باشید که در این حالت دستور ``return`` تمام این اشیا را در قالب یک شی تاپل برمی‌گرداند:: +توجه داشته باشید که در این حالت دستور ``return`` تمام این اشیا را در قالب یک شی توپِل برمی‌گرداند:: >>> multiple(X, Y) (2, [3, 4]) @@ -508,7 +508,7 @@ TypeError: f() got multiple values for argument 'a' -* سینتکس ``iterable*``، در این سینتکس یک شی از نوع تکرارپذیر (iterable - درس نهم) مانند انواع رشته، تاپل، لیست و... که توسط یک کاراکتر ستاره ``*‍‍`` نشانه‌گذاری شده است، به تابع ارسال می‌گردد. در این صورت بر اساس ترتیب موقعیت، اعضای درون شی تکرارپذیر به پارامتر‌های تابع اختصاص می‌یابند:: +* سینتکس ``iterable*``، در این سینتکس یک شی از نوع تکرارپذیر (iterable - درس نهم) مانند انواع رشته، توپِل، لیست و... که توسط یک کاراکتر ستاره ``*‍‍`` نشانه‌گذاری شده است، به تابع ارسال می‌گردد. در این صورت بر اساس ترتیب موقعیت، اعضای درون شی تکرارپذیر به پارامتر‌های تابع اختصاص می‌یابند:: >>> def f(a, b, c): ... print("a= ", a) @@ -600,7 +600,7 @@ -* سینتکس ``name*``، تمام آرگومان‌های ارسالی را در قالب یه شی تاپل دریافت می‌کند - این قابلیت در مواقعی که تعداد آرگومان‌های ارسالی متغییر است کمک بزرگی می‌کند:: +* سینتکس ``name*``، تمام آرگومان‌های ارسالی را در قالب یه شی توپِل دریافت می‌کند - این قابلیت در مواقعی که تعداد آرگومان‌های ارسالی متغییر است کمک بزرگی می‌کند:: >>> def f(*name): ... print(type(name)) diff --git a/source/lessons/l13.rst b/source/lessons/l13.rst index 0a0acd5..395111e 100644 --- a/source/lessons/l13.rst +++ b/source/lessons/l13.rst @@ -373,7 +373,7 @@ Generator 4 >>> -به منظور درک بهتر عملکرد تابع Generator‌، تصور کنید از شما خواسته شده است که یک تابع شخصی مشابه با تابع ``()range`` پایتون پیاده‌سازی نمایید. راهکار شما چه خواهد بود؟ ایجاد یک شی‌ای مانند لیست (list) یا تاپل خالی و پر کردن آن با استفاده از یک حلقه؟! این راهکار شاید برای ایجاد بازه‌های کوچک پاسخگو باشد ولی برای ایجاد یک بازه صد میلیونی آیا حافظه و زمان کافی در اختیار دارید؟. این مسئله را با استفاده از تابع Generator‌ به سادگی و درستی حل خواهیم کرد:: +به منظور درک بهتر عملکرد تابع Generator‌، تصور کنید از شما خواسته شده است که یک تابع شخصی مشابه با تابع ``()range`` پایتون پیاده‌سازی نمایید. راهکار شما چه خواهد بود؟ ایجاد یک شی‌ای مانند لیست (list) یا توپِل خالی و پر کردن آن با استفاده از یک حلقه؟! این راهکار شاید برای ایجاد بازه‌های کوچک پاسخگو باشد ولی برای ایجاد یک بازه صد میلیونی آیا حافظه و زمان کافی در اختیار دارید؟. این مسئله را با استفاده از تابع Generator‌ به سادگی و درستی حل خواهیم کرد:: >>> def my_range(stop): ... number = 0 @@ -623,7 +623,7 @@ List Comprehensions [2.23606797749979, 5.0, 7.810249675906654] -توجه داشته باشید، چنانچه نتیجه اعمال List Comprehensions در هر نوبت شامل بیش از یک عضو باشد، می‌بایست مقادیر نتایج در داخل یک پرانتز قرار داده شوند (به صورت یک شی تاپل - tuple). +توجه داشته باشید، چنانچه نتیجه اعمال List Comprehensions در هر نوبت شامل بیش از یک عضو باشد، می‌بایست مقادیر نتایج در داخل یک پرانتز قرار داده شوند (به صورت یک شی توپِل - tuple). به نمونه ``[x,y) for x in a for y in b if x > 0)]`` و خروجی آن توجه نمایید. با توجه به این موضوع عبارت زیر از نظر مفسر پایتون نادرست می‌باشد:: diff --git a/source/lessons/l16.rst b/source/lessons/l16.rst index 0a6ef65..36c826f 100644 --- a/source/lessons/l16.rst +++ b/source/lessons/l16.rst @@ -117,7 +117,7 @@ * ``Match.group([group1, ...])`` [`اسناد پایتون `__] - این متد از شی ``Match``، گروه (های) تطبیق داده شده بر اساس الگو مورد نظر را برمی‌گرداند. این متد می‌تواند یک یا چند آرگومان عددی دریافت کند که معرف اندیس گروه مورد نظر می‌باشد. در حالت فراخوانی بدون آرگومان تمامی گروه‌های تطبیق داده شده به صورت یک مقدار رشته برگردانده می‌شود و در صورتی تنها یک مقدار به آن ارسال گردد، گروه تطبیق داده شده متناظر با آن اندیس (شمارش اندیس‌ها از یک است) در قالب یک شی رشته برگردانده می‌شود و در صورتی که بیش از یک اندیس به عنوان آرگومان ارسال گردد یک شی تاپل محتوی گروه‌های تطبیق داده شده برگردانده خواهد شد. چنانچه آرگومان ارسالی عددی منفی باشد یا اندیسی بالاتر از تعداد گروه‌های تطبیق داده شده باشد، یک استثنا ``IndexError`` رخ خواهد داد:: + این متد از شی ``Match``، گروه (های) تطبیق داده شده بر اساس الگو مورد نظر را برمی‌گرداند. این متد می‌تواند یک یا چند آرگومان عددی دریافت کند که معرف اندیس گروه مورد نظر می‌باشد. در حالت فراخوانی بدون آرگومان تمامی گروه‌های تطبیق داده شده به صورت یک مقدار رشته برگردانده می‌شود و در صورتی تنها یک مقدار به آن ارسال گردد، گروه تطبیق داده شده متناظر با آن اندیس (شمارش اندیس‌ها از یک است) در قالب یک شی رشته برگردانده می‌شود و در صورتی که بیش از یک اندیس به عنوان آرگومان ارسال گردد یک شی توپِل محتوی گروه‌های تطبیق داده شده برگردانده خواهد شد. چنانچه آرگومان ارسالی عددی منفی باشد یا اندیسی بالاتر از تعداد گروه‌های تطبیق داده شده باشد، یک استثنا ``IndexError`` رخ خواهد داد:: >>> match = re.search("(\w+) (\w+)", "Isaac Newton, physicist") >>> match.group() # The entire match @@ -151,7 +151,7 @@ * ``Match.groups(default=None)`` [`اسناد پایتون `__] - این متد تمام گروه‌های تطبیق داده شده بر اساس الگو مورد نظر را در قالب یک شی تاپل برمی‌گرداند. این متد می‌تواند یک آرگومان بپذیرد که معرف مقدار پیش‌فرض برای جایگذاری گروه‌هایی است که در رشته ورودی تطبیق داده نشده‌اند، در حالت عادی (بدون ارسال آرگومان) این مقدار برابر با ``None`` است:: + این متد تمام گروه‌های تطبیق داده شده بر اساس الگو مورد نظر را در قالب یک شی توپِل برمی‌گرداند. این متد می‌تواند یک آرگومان بپذیرد که معرف مقدار پیش‌فرض برای جایگذاری گروه‌هایی است که در رشته ورودی تطبیق داده نشده‌اند، در حالت عادی (بدون ارسال آرگومان) این مقدار برابر با ``None`` است:: >>> match = re.search("(\d+)\.(\d+)", "24.1632") >>> match.groups() @@ -303,7 +303,7 @@ * ``Match.span([group])`` [`اسناد پایتون `__] - این متد یک شی تاپل دوتایی از خروجی دو متد ``start`` و ``end`` را بر می‌گرداند و همانند آنها نیز یک آرگومان اختیاری دارد - نمونه خروجی: ``(m.start(group), m.end(group))``:: + این متد یک شی توپِل دوتایی از خروجی دو متد ``start`` و ``end`` را بر می‌گرداند و همانند آنها نیز یک آرگومان اختیاری دارد - نمونه خروجی: ``(m.start(group), m.end(group))``:: >>> match = re.search(r"(\d+)\.(\d+)", "24.1632") >>> match.span() @@ -489,7 +489,7 @@ >>> print(results) ['#Perl#', '#Python#', '#Ruby#'] -چنانچه الگو شامل بیش از یک گروه باشد، خروجی تابع ``findall`` برابر است با یک لیست از تاپل‌ها که هر تاپل، حاصل یک دور انطباق است:: +چنانچه الگو شامل بیش از یک گروه باشد، خروجی تابع ``findall`` برابر است با یک لیست از توپِل‌ها که هر توپِل، حاصل یک دور انطباق است:: >>> results = re.findall(r'(\w+)@(\d+)', 'Perl@1987,Python@1991,Ruby@1995') >>> print(results) @@ -700,7 +700,7 @@ ``subn(pattern, repl, string, count=0, flags=0)`` -عملکرد این تابع (``subn``) همانند تابع ``sub`` است. تنها تفاوت در خروجی آن‌هاست، تابع ``subn`` یک شی تاپل محتوی نتیجه و تعداد عملیات جایگذاری را برمی‌گرداند [`اسناد پایتون `__]:: +عملکرد این تابع (``subn``) همانند تابع ``sub`` است. تنها تفاوت در خروجی آن‌هاست، تابع ``subn`` یک شی توپِل محتوی نتیجه و تعداد عملیات جایگذاری را برمی‌گرداند [`اسناد پایتون `__]:: >>> import re # Python 3.x diff --git a/source/lessons/l18.rst b/source/lessons/l18.rst index 3558573..414b351 100644 --- a/source/lessons/l18.rst +++ b/source/lessons/l18.rst @@ -377,7 +377,7 @@ **Method Resolution Order** ، همانطوری که از نام آن نیز مشخص است، **MRO** ترتیبی که می‌بایست بر اساس آن متدها جستجو شوند را پیدا می‌کند. پایتون برای این منظور از الگوریتم C3 linearization بهره گرفته است [`ویکی‌پدیا `__] (البته از نسخه 2.3 به بعد) [`اسناد پایتون `__]. -هر کلاس پایتون یک Special Attribute به اسم ``__mro__`` دارد که حاوی یک تاپل از ترتیب کلاس‌هایی است که پایتون بر اساس آن به دنبال یک متد می‌گردد [`اسناد پایتون `__]، در واقع این مقدار حاصل تلاش MRO بر اساس محاسبه الگوریتم C3 linearization برای آن کلاس خواهد بود. برای مثال این مقدار برای کلاس ``SubClass`` ما برابر است با:: +هر کلاس پایتون یک Special Attribute به اسم ``__mro__`` دارد که حاوی یک توپِل از ترتیب کلاس‌هایی است که پایتون بر اساس آن به دنبال یک متد می‌گردد [`اسناد پایتون `__]، در واقع این مقدار حاصل تلاش MRO بر اساس محاسبه الگوریتم C3 linearization برای آن کلاس خواهد بود. برای مثال این مقدار برای کلاس ``SubClass`` ما برابر است با:: >>> SubClass.__mro__ diff --git a/source/lessons/l19.rst b/source/lessons/l19.rst index db92567..403d6b2 100644 --- a/source/lessons/l19.rst +++ b/source/lessons/l19.rst @@ -191,7 +191,7 @@ با استفاده از مثال پیش، یک کاربرد جالب و مهم از قابلیت تعریف متا کلاس در پایتون را بررسی کردیم، مثالی که شما را با روند ایجاد شی نیز بیشتر آشنا کرد. -در انتهای این بخش جا دارد با امکان تعریف یک متد از نوع Class Method به نام ``__prepare__`` [`اسناد پایتون `__] در پایتون آشنا شویم. به صورت پیش‌فرض مفسر پایتون پس از اینکه متا کلاسِ یک کلاس را تشخیص می‌دهد، بلافاصله به دنبال ``__prepare__`` در آن می‌گردد و چنانچه پیاده‌سازی شده باشد، آن را فراخوانی و آرگومان‌های «متا کلاس»، «نام کلاسی که قرار است یک شی از آن ایجاد گردد»، «یک شی تاپل حاوی فهرست superclassهای آن کلاس - با حفظ ترتیب» و «تعدادی keyword argumentهای احتمالی (آرگومان‌های نام=مقدار)» را به آن ارسال می‌کند [`PEP 3115 `__]. خروجی این متد می‌بایست یک شی دیکشنری (``dict``) باشد که در زمان ایجاد و ارزیابی کلاس، مورد استفاده قرار می‌گیرد. این متد قبل از ``__call__`` فراخوانی می‌شود و ما می‌توانیم از آن برای قرار دادن مقادیری برای استفاده در کلاس‌هایی که توسط متا کلاس ایجاد می‌گردند قرار دهیم. برای درک بهتر کاربرد این متد، به نمونه کد زیر توجه نمایید: +در انتهای این بخش جا دارد با امکان تعریف یک متد از نوع Class Method به نام ``__prepare__`` [`اسناد پایتون `__] در پایتون آشنا شویم. به صورت پیش‌فرض مفسر پایتون پس از اینکه متا کلاسِ یک کلاس را تشخیص می‌دهد، بلافاصله به دنبال ``__prepare__`` در آن می‌گردد و چنانچه پیاده‌سازی شده باشد، آن را فراخوانی و آرگومان‌های «متا کلاس»، «نام کلاسی که قرار است یک شی از آن ایجاد گردد»، «یک شی توپِل حاوی فهرست superclassهای آن کلاس - با حفظ ترتیب» و «تعدادی keyword argumentهای احتمالی (آرگومان‌های نام=مقدار)» را به آن ارسال می‌کند [`PEP 3115 `__]. خروجی این متد می‌بایست یک شی دیکشنری (``dict``) باشد که در زمان ایجاد و ارزیابی کلاس، مورد استفاده قرار می‌گیرد. این متد قبل از ``__call__`` فراخوانی می‌شود و ما می‌توانیم از آن برای قرار دادن مقادیری برای استفاده در کلاس‌هایی که توسط متا کلاس ایجاد می‌گردند قرار دهیم. برای درک بهتر کاربرد این متد، به نمونه کد زیر توجه نمایید: .. code-block:: python :linenos: diff --git a/source/lessons/l21.rst b/source/lessons/l21.rst index 4c45e5c..0603051 100644 --- a/source/lessons/l21.rst +++ b/source/lessons/l21.rst @@ -271,7 +271,7 @@ __slots__ TypeError: multiple bases have instance lay-out conflict -بهتر است superclassها حاوی یک ``__slots__`` خالی (شی تاپل خالی) باشند و هر subclass خود محتوای ``__slots__`` خود را تعریف نماید: +بهتر است superclassها حاوی یک ``__slots__`` خالی (شی توپِل خالی) باشند و هر subclass خود محتوای ``__slots__`` خود را تعریف نماید: .. code-block:: python :linenos: diff --git a/source/lessons/l22.rst b/source/lessons/l22.rst index 7ddaf51..72c05cd 100644 --- a/source/lessons/l22.rst +++ b/source/lessons/l22.rst @@ -681,7 +681,7 @@ Type Hinting تابع ``field`` و ``fields`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -تابع ``fields`` از ماژول ``dataclasses`` یک شی از دیتا کلاس یا خود دیتا کلاس را از ورودی دریافت و یک تاپل حاوی تمام فیلد‌های آن بر می‌گرداند [`اسناد پایتون `__]: +تابع ``fields`` از ماژول ``dataclasses`` یک شی از دیتا کلاس یا خود دیتا کلاس را از ورودی دریافت و یک توپِل حاوی تمام فیلد‌های آن بر می‌گرداند [`اسناد پایتون `__]: .. code-block:: python :linenos: diff --git a/source/lessons/l23.rst b/source/lessons/l23.rst index 9bcd03c..c0a7ba5 100644 --- a/source/lessons/l23.rst +++ b/source/lessons/l23.rst @@ -284,7 +284,7 @@ ZeroDivisionError: (0+8)/0 -چنانچه مکانیزم مدیریت خطای شما برای چندین نوع Exception مشخص یکسان است می‌توانید آن دستورهای ``except`` را با یکدیگر ترکیب کرد و تنها از یک دستور ``except`` استفاده نمایید. برای این منظور تنها کافی است نام تمام Exceptionهای مورد نظر خود را در قالب یک شی تاپل به دستور ``except`` بسپرید: +چنانچه مکانیزم مدیریت خطای شما برای چندین نوع Exception مشخص یکسان است می‌توانید آن دستورهای ``except`` را با یکدیگر ترکیب کرد و تنها از یک دستور ``except`` استفاده نمایید. برای این منظور تنها کافی است نام تمام Exceptionهای مورد نظر خود را در قالب یک شی توپِل به دستور ``except`` بسپرید: .. code-block:: python :linenos: diff --git a/source/log.rst b/source/log.rst index 150de57..629af2d 100644 --- a/source/log.rst +++ b/source/log.rst @@ -12,11 +12,22 @@ ============= +.. raw:: html + +

00131 - پنج‌شنبه ۳۱ فروردین ۱۴۰۲

+ +* درس هشتم ویرایش و بروزرسانی گردید. +* جهت کاهش محتوا و آسانی در مطالعه، درس هشتم در قالب دو صفحه مجزا ارایه گردید. +* شرح شی None از درس هشتم به درس ششم منتقل گردید. + + +---- + .. raw:: html

00130 - جمعه ۲۵ فروردین ۱۴۰۲

-* درس هفتم مورد ویرایش قرار گرفت و بروزرسانی گردید. +* درس هفتم ویرایش و بروزرسانی گردید. * جهت کاهش محتوا و آسانی در مطالعه، درس هفتم در قالب دو صفحه مجزا ارایه گردید.