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 0000000..7178baf Binary files /dev/null and b/source/_static/pages/08-python-built-in-data-types-3.jpg differ 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/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/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/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 new file mode 100644 index 0000000..de66a2c --- /dev/null +++ b/source/lessons/l08-list-and-tuple-in-python.rst @@ -0,0 +1,1075 @@ +.. role:: emoji-size + +.. meta:: + :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان‌های داده در پایتون، list و tuple + :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان‌های داده در پایتون, list در پایتون, tuple در پایتون + + +.. _lesson-08.1: + +درس ۰۸: ساختمان‌های داده در پایتون: list و tuple +==================================================================================== + +.. figure:: /_static/pages/08-python-built-in-data-types-3.jpg + :align: center + :alt: درس ۰۸: ساختمان‌های داده در پایتون: tuple و list + :class: page-image + + Photo by `Maria Orlova `__ + + +از درس هفتم با انواع داده پایه در پایتون آشنا شده‌ایم و در این درس به بررسی انواع داده دیگری خواهیم پرداخت که در زبان‌های برنامه‌نویسی عموما با عنوان ساختمان‌های داده بیان می‌شوند. ساختمان‌های داده یا Data Structures به اشیایی گفته می‌شود که برای نگهداری از یک مجموعه داده طراحی شده‌اند و هر یک دارای ویژگی منحصربه‌فرد خود است. برای مثال قابل تغییر بودن، امکان حفظ ترتیب اعضا، امکان نگهداری داده‌های تکراری یا تنها اجبار به نگهداری داده‌های یکتا که هر یک مناسب وضعیت خاصی در برنامه‌نویسی هستند. این درس به بررسی چهار ساختمان داده متداول در پایتون خواهد پرداخت: لیست (list)، توپِل (tuple)، مجموعه (set) و دیکشنری (dict) + + +به منظور جلوگیری از طولانی شدن متن درس و همینطور سادگی در مطالعه، محتوا این درس در قالب دو بخش ارایه می‌شود که بخش نخست تنها به شرح لیست (list) و توپِل (tuple) خواهد پرداخت. + + + + +:emoji-size:`✔` سطح: مقدماتی + +---- + +.. contents:: سرفصل‌ها + :depth: 2 + +---- + +.. _python-list: + +لیست +------ + +نوع «**لیست**» (List) یک نوع بسیار انعطاف‌پذیر در پایتون می‌باشد. این نوع همانند رشته یک «**دنباله**» (Sequence) بوده ولی برخلاف آن یک نوع «**تغییر پذیر**» (Mutable) است. شی لیست با استفاده از کروشه ``[ ]`` ایجاد می‌گردد و ترتیب اعضا را حفظ و می‌تواند عضوهایی - **از هر نوع** - داشته باشد که توسط کاما ``,`` از یکدیگر جدا می‌شوند؛ نوع لیست در واقع محلی برای نگهداری اشیا گوناگون و تغییرپذیر است:: + + >>> L = [1, 2, 3] + >>> type(L) + + + >>> L + [1, 2, 3] + >>> print(L) + [1, 2, 3] + + >>> import sys + >>> sys.getsizeof(L) + 88 + +:: + + >>> L = [] # An empty list + >>> L + [] + + +عضوهای لیست می‌توانند از هر نوعی باشند؛ حتی یک لیست:: + + >>> L = [15, 3.14, 'string', [1, 2]] + + +شی لیست جزو انواع دنباله پایتون است و می‌توان عضوها را بر اساس اندیس موقعیت آن‌ها دستیابی نمود:: + + >>> L = [1, 2, 3] + >>> L[0] + 1 + >>> L[-1] + 3 + +و همچنین تعداد عضوهای هر شی لیست را توسط تابع ``()len`` [`اسناد پایتون `__] به دست آورد:: + + >>> L1 = [] + >>> len(L1) + 0 + + >>> L2 = ['python', 12.06] + >>> len(L2) + 2 + + >>> len(L2[0]) + 6 + + >>> L3 = ['a', [1, 2], 'b'] + >>> len(L3) + 3 + >>> len(L3[1]) + 2 + + + + +چنانچه یک دنباله جزو عضوهای شی لیست باشد، با استفاده از الگو ``[seq[i][j`` می‌توان عضوهای آن را نیز دستیابی نمود که در آن ``i`` اندیسی است که به یک عضو شی لیست اشاره دارد و ``j`` نیز اشاره به اندیس داخلی عضو ``i`` دارد؛ این الگو به همین شیوه می‌تواند ادامه یابد:: + + >>> L = ['python', 2.56] + >>> L[0] + 'python' + >>> L[0][:2] + 'py' + + >>> L = ['python', 2.56, [128, ['a', 'z']]] + >>> L[2][1][0] + 'a' + + +یکی از مثال‌های رایج شی لیست‌، شبیه‌سازی ساختار ماتریس (`Matrix `_) است:: + + >>> L = [[1, 2, 3], + ... [4, 5, 6], + ... [7, 8, 9]] + >>> + + >>> L + [[1, 2, 3], [4, 5, 6], [7, 8, 9]] + + >>> L[0][1] + 2 + + + + +شی لیست جزو انواع Mutable پایتون است و می‌توان عضوهای آن را تغییر داد؛ این تغییر می‌تواند به شکل حذف، درج عضو جدید یا جایگزین کردن یک یا چند عضو باشد. پایتون متدهای کاربردی زیادی برای دستکاری و تغییر شی لیست دارد که در ادامه به آن‌ها نیز خواهیم پرداخت ولی در این بخش می‌خواهیم به بررسی چگونگی ایجاد تغییر با استفاده از عملگر انتساب بپردازیم: + + +* جایگزین کردن:: + + >>> L = [1, 2, 3] + + >>> L[1] = 'py' + >>> L + [1, 'py', 3] + + :: + + >>> L = [1, 2, 3, 4, 5, 6] + + >>> L[:2] = [0, 0] + >>> L + [0, 0, 3, 4, 5, 6] + +* درج کردن - ``i`` در الگو ``[seq[i:i`` به موقعیتی از شی ``seq`` اشاره دارد که می‌خواهیم درج در آن نقطه انجام شود؛ در این شیوه توجه داشته باشید که شی‌ای که می‌خواهید درون لیست درج کنید می‌بایست یک دنباله باشد:: + + >>> L = [0, 1, 5, 6] + + >>> L[2:2] = [2, 3, 4] + >>> L + [0, 1, 2, 3, 4, 5, 6] + + >>> L[0:0] = 'abc' + >>> L + ['a', 'b', 'c', 0, 1, 2, 3, 4, 5, 6] + + >>> L[3:3] = ['d', [-2, -1]] + >>> L + ['a', 'b', 'c', 'd', [-2, -1], 0, 1, 2, 3, 4, 5, 6] + + +* حذف کردن - کافی است یک شی لیست خالی (``[]``) را به یک یا چند عضو از شی لیست مورد نظر انتساب دهیم:: + + >>> L = [0, 1, 2, 3, 4, 5, 6] + + >>> L[2:5] = [] + >>> L + [0, 1, 5, 6] + + +.. _python-del: + +دستور ``del`` +~~~~~~~~~~~~~~~~~ + +با استفاده از دستور ``del`` [`اسناد پایتون `__] نیز می‌توان یک عضو یا یک تکه از شی لیست را حذف کرد:: + + >>> L = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + + >>> del L[2] + >>> L + ['a', 'b', 'd', 'e', 'f', 'g'] + + >>> del L[1:4] + >>> L + ['a', 'f', 'g'] + +همچنین می‌توانیم از این دستور برای حذف کامل یک متغیر استفاده نماییم. با حدف یک متغیر، ارجاع آن به شی نیز حذف می‌شود و چنانچه هیچ ارجاع دیگری به آن شی وجود نداشته باشد، شی‌ای که متغیر به آن ارجاع داشت نیز از حافظه حذف می‌گردد:: + + >>> a = 5 + >>> a + 5 + + >>> del a + + >>> a + Traceback (most recent call last): + File "", line 1, in + NameError: name 'a' is not defined + + +.. _python-unpacking: + +انتساب چندگانه +~~~~~~~~~~~~~~~~~~~~ + +می‌توان یک شی لیست - یا در کل یک شی دنباله - را به تعدادی نام انتساب داد و متغیرهای جداگانه‌ای ایجاد نمود؛ این عمل **Unpacking** خوانده می‌شود. در این شرایط مفسر پایتون هر عضو دنباله را با حفظ ترتیب به یکی از نام‌ها انتساب می‌دهد که در حالت عادی می‌بایست تعداد نام‌ها با عضوهای دنباله برابر باشد:: + + >>> L = [1.1, 2.2, 3.3, 4.4] + + >>> a, b, c, d = L + + >>> a + 1.1 + >>> b + 2.2 + >>> c + 3.3 + >>> d + 4.4 + +:: + + >>> a, b = [1.1, 2.2, 3.3, 4.4] + Traceback (most recent call last): + File "", line 1, in + ValueError: too many values to unpack (expected 2) + +ولی می‌توان یکی از نام‌ها را توسط نماد ``*`` نشانه‌گذاری کرد؛ در این شرایط مفسر پایتون توازنی را بین عضوهای دنباله و نام‌ها ایجاد می‌کند که در این حالت تمام عضوهای اضافی - در قالب یک شی لیست - به نام نشانه‌گذاری شده انتساب داده می‌شود. البته باید توجه داشت که ترتیب عضوهای دنباله در هر شرایطی رعایت خواهد شد؛ به نمونه کدهای پایین توجه نمایید:: + + >>> L = [1.1, 2.2, 3.3, 4.4] + + >>> a, b, *c = L + + >>> a + 1.1 + >>> b + 2.2 + >>> c + [3.3, 4.4] + +:: + + >>> *a, b = [1.1, 2.2, 3.3, 4.4] + + >>> a + [1.1, 2.2, 3.3] + >>> b + 4.4 + +:: + + >>> a, *b, c = [1.1, 2.2, 3.3, 4.4] + + >>> a + 1.1 + >>> b + [2.2, 3.3] + >>> c + 4.4 + +:: + + >>> a, b, c, *d = [1.1, 2.2, 3.3, 4.4] + + >>> a + 1.1 + >>> b + 2.2 + >>> c + 3.3 + >>> d + [4.4] + + +.. _python-copy: + +کپی کردن +~~~~~~~~~~~~~~~~ + +همانند دیگر اشیا می‌توان با انتساب یک متغیر موجود از شی لیست به یک نام جدید، متغیر دیگری از این نوع شی ایجاد کرد. البته همانطور که پیش‌تر نیز بیان شده است؛ در این حالت شی کپی نمی‌گردد و تنها یک ارجاع جدید از این نام جدید به شی آن متغیر داده می‌شود. این موضوع با استفاده از تابع ``()id`` [`اسناد پایتون `__] قابل آزمودن است؛ خروجی این تابع برابر نشانی شی در حافظه می‌باشد و بدیهی است که دو مقدار id یکسان برای دو متغیر نشان از یکی بودن شی آن‌هاست:: + + >>> L1 = [1, 2, 3] + + >>> L2 = L1 + + >>> L2 + [1, 2, 3] + + >>> id(L1) + 140254551721800 + >>> id(L2) + 140254551721800 + + +عضوهای یک شی لیست تغییر پذیر هستند و باید توجه داشته باشیم اکنون که هر دو متغیر به یک شی اشاره دارند اگر توسط یکی از متغیرها، عضوهای شی مورد نظر تغییر داده شوند، مقدار مورد انتظار ما از شی متغیر دوم نیز تغییر خواهد کرد:: + + >>> L1 = [1, 2, 3] + + >>> L2 = L1 + + >>> L1[0] = 7 + + >>> L1 + [7, 2, 3] + >>> L2 + [7, 2, 3] + +اگر این موضوع را یک مشکل بدانیم برای رفع آن می‌توان از شی متغیر یک کپی ایجاد کرده و این کپی را به متغیر جدید نسبت دهیم؛ در این شرایط هر دو متغیر به اشیایی جداگانه در محل‌هایی متفاوت از حافظه اشاره خواهند داشت. در حالت عادی برای کپی کردن یک شی لیست نیاز به کار جدیدی نیست و می‌توان از اندیس گذاری ``[:]`` - به معنی تمامی عضوها - استفاده کرد:: + + >>> L1 + [7, 2, 3] + + >>> L2 = L1[:] + + >>> L1 + [7, 2, 3] + >>> L2 + [7, 2, 3] + + >>> id(L1) + 140254551721928 + >>> id(L2) + 140254551721800 + + >>> L1[0] = 5 + + >>> L1 + [5, 2, 3] + >>> L2 + [7, 2, 3] + +.. image:: /_static/l08-python-list-assignment-01.png + :align: center + +ولی اگر شی لیست مورد نظر عضوهایی از نوع لیست (یا هر نوع تغییر پذیر دیگر) داشته باشد، مشکل فوق همچنان برای این عضوها باقی است. به نمونه کد و تصویر پایین توجه نمایید:: + + >>> L1 = [1, 2, [7, 8]] + + >>> L2 = L1[:] + >>> L2 + [1, 2, [7, 8]] + + >>> L1[2][1] = 5 + + >>> L1 + [1, 2, [7, 5]] + >>> L2 + [1, 2, [7, 5]] + + >>> id(L1) + 140402644179400 + >>> id(L2) + 140402651379720 + + >>> id(L1[2]) + 140402644179080 + >>> id(L2[2]) + 140402644179080 + + + +.. image:: /_static/l08-python-list-assignment-02.png + :align: center + +در پایتون کپی شی به دو شیوه **«سطحی»** (Shallow Copy) و **«عمیق»** (Deep Copy) انجام می‌شود که به ترتیب توسط تابع‌های ``()copy`` و ``()deepcopy`` از درون ماژول ``copy`` در دسترس هستند [`اسناد پایتون `__]. در شیوه کپی سطحی همانند کاری که پیش از این انجام دادیدم - یعنی انتساب با استفاده از اندیس ``[:]`` - اشیا داخلی کپی نمی‌شوند و تنها یک ارجاع جدید به آن‌ها داده می‌شود؛ در حالی که توسط شیوه کپی عمیق از تمامی اشیا (تغییر پذیر) داخلی نیز یک کپی ایجاد می‌گردد:: + + >>> L1 = [1, 2, [7, 8]] + + >>> import copy + >>> L2 = copy.copy(L1) # Shallow Copy + + >>> L1[2][1] = 5 + + >>> L1 + [1, 2, [7, 5]] + >>> L2 + [1, 2, [7, 5]] + +:: + + >>> L1 = [1, 2, [7, 8]] + + >>> import copy + >>> L2 = copy.deepcopy(L1) # Deep Copy + + >>> L1[2][1] = 5 + + >>> L1 + [1, 2, [7, 5]] + >>> L2 + [1, 2, [7, 8]] + + >>> id(L1) + 140402651379656 + >>> id(L2) + 140402644179400 + + >>> id(L1[2]) + 140402644106312 + >>> id(L2[2]) + 140402651379080 + + +.. _python-list-operators: + +عملگرها برای لیست +~~~~~~~~~~~~~~~~~~~~~~~~~ + +می‌توان از عملگرهای ``+`` (برای پیوند لیست‌ها) و ``*`` (برای تکرار عضوهای لیست) بهره برد:: + + >>> [1, 2] + [2, 3] + [3, 4] + [1, 2, 2, 3, 3, 4] + + >>> ['python'] * 3 + ['python', 'python', 'python'] + + +برای بررسی برابر بودن مقدار دو شی لیست مانند دیگر اشیا می‌توان از عملگر ``==`` استفاده کرد:: + + >>> [1, 'python'] == [1, 'python'] + True + + >>> [1, 'python'] == [1, 'PYTHON'] + False + +از عملگرهای عضویت هم می‌توان برای بررسی وجود شی‌ای درون لیست استفاده کرد:: + + >>> L = ['a', [1, 2]] + + >>> 'b' not in L + True + >>> 2 in L + False + >>> [1, 2] in L + True + + +.. _python-is-va-equal: + +تفاوت عملگرهای ``==`` و ``is`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +نکته‌ای که در درس‌های پیش مطرح نشد، بیان تفاوت بین عملگر برابری و عملگر هویت است. پیش از ارایه توضیح به نمونه کد پایین توجه نمایید:: + + >>> a = 5 + >>> b = a + >>> a == b + True + >>> a is b + True + + >>> L1 = [1, 2, 3] + >>> L2 = L1 + >>> L1 == L2 + True + >>> L1 is L2 + True + + >>> L2 = L1[:] + >>> L1 == L2 + True + >>> L1 is L2 # False! + False + + +از درس پنجم به یاد داریم که هر شی در پایتون حاوی یک «شناسه» (identity)، یک «نوع» (type) و یک «مقدار» (value) است. عملگر ``==`` دو شی را از نظر یکسان بودن «مقدار» مورد بررسی قرار می‌دهد در حالی که عملگر ``is`` دو شی را از نظر یکسان بودن «شناسه» (خروجی تابع ``()id``) یا همان نشانی آن‌ها در حافظه مورد بررسی قرار می‌دهد. + +پیش از این هم بیان شده بود که مفسر پایتون برای صرفه‌جویی در زمان و حافظه از ساخت مجدد اشیا نوع «صحیح» و «رشته» کوچک موجود اجتناب می‌کند و تنها یک ارجاع جدید به آن‌ها می‌دهد. اما این موضوع در مورد اشیا دیگر درست نمی‌باشد و مفسر پایتون برای هر متغیری که برای این نوع اشیا تعریف می‌گردد یک شی جدید ایجاد می‌کند و به آن ارجاع می‌دهد:: + + >>> a = 5 + >>> b = 5 + >>> a == b + True + >>> a is b + True + + >>> m = 'python' + >>> n = 'python' + >>> m == n + True + >>> m is n + True + + >>> L1 = [1, 2, 3] + >>> L2 = [1, 2, 3] + >>> L1 == L2 + True + >>> L1 is L2 # False! + False + +.. _python-convert-to-list: + +تبدیل به شی لیست +~~~~~~~~~~~~~~~~~~~~~~~~~ + +با استفاده از کلاس ``()list`` [`اسناد پایتون `__] می‌توان یک شی لیست ایجاد کرد یا اشیایی که از نوع دنباله هستند را به یک شی لیست تبدیل نمود:: + + >>> a = 'python' + >>> type(a) + + + >>> b = list(a) + >>> type(b) + + + >>> b + ['p', 'y', 't', 'h', 'o', 'n'] + +:: + + >>> L = list() + >>> L + [] + + +.. _python-list-methods: + +متدهای کاربردی یک شی لیست +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +شی لیست تغییر پذیر است و متدهای آن برخلاف شی رشته یک شی جدید تغییر یافته را برنمی‌گردانند بلکه تغییرات را بر روی همان شی ایجاد می‌کنند. + +* ``(append(x`` - شی ``x`` را به انتهای لیست مورد نظر اضافه می‌کند:: + + >>> L = [1, 2, 3] + + >>> L.append(4) + >>> L + [1, 2, 3, 4] + + >>> L.append(['a', 'b']) + >>> L + [1, 2, 3, 4, ['a', 'b']] + + عملکرد این متد ``(L.append(x`` همانند عمل ``[L + [x`` است:: + + >>> L = [1, 2, 3] + >>> L + [4] + [1, 2, 3, 4] + + +* ``(extend(s`` - عضوهای شی دنباله ``s`` را به انتهای لیست مورد نظر اضافه می‌کند:: + + >>> L = [1, 2, 3] + + >>> L.extend(['a', 'b']) + >>> L + [1, 2, 3, 'a', 'b'] + + :: + + >>> L = [1, 2, 3] + + >>> L.extend('py') + >>> L + [1, 2, 3, 'p', 'y'] + + +* ``(insert(i, x`` - یک عضو جدید مانند ``x`` را در موقعیتی از لیست با اندیس دلخواه مانند ``i`` قرار می‌دهد:: + + >>> L = [1, 2, 3] + + >>> L.insert(0, 'python') + >>> L + ['python', 1, 2, 3] + +* ``(remove(x`` - در لیست مورد نظر از سمت چپ به دنبال شی‌ ``x`` می‌گردد و نخستین مورد یافت شده را از لیست حذف می‌کند. چنانچه هیچ عضو برابری با شی ``x`` یافت نشود یک خطا گزارش می‌دهد:: + + >>> L = [1, 2, 3, 5, 2 , 6 , 1] + + >>> L.remove(2) + >>> L + [1, 3, 5, 2, 6, 1] + + >>> L.remove(0) + Traceback (most recent call last): + File "", line 1, in + ValueError: list.remove(x): x not in list + + .. note:: + در مواردی که می‌خواهید اندیس خاصی از لیست را حذف نمایید؛ از دستور ``del`` استفاده کنید. + + +* ``([pop([i`` - عضو متناظر با اندیس ``i`` را از لیست حذف و به عنوان خروجی برمی‌گرداند. چنانچه اندیس به متد فرستاده نشود به صورت پیش‌فرض **آخرین عضو** از لیست مورد نظر را حذف و برمی‌گرداند:: + + >>> L = ['a', 'b', 'c', 'd'] + + >>> L.pop(2) + 'c' + >>> L + ['a', 'b', 'd'] + + >>> L.pop() + 'd' + >>> L + ['a', 'b'] + + .. note:: + نماد ``[ ]`` در الگو متدها تنها روشی برای بیان اختیاری بودن عبارت درون آن می‌باشد و جزیی از متد نیست. + + +* ``([index(x[, n`` - در لیست مورد نظر از سمت چپ به دنبال شی ``x`` می‌گردد و اندیس نخستین مورد یافت شده را برمی‌گرداند. این متد یک آرگومان اختیاری (``n``) نیز دارد که به کمک آن می‌توان تعیین نمود اندیس چندمین مورد یافت شده برگردانده شود. چنانچه هیچ عضو برابری با شی ``x`` یافت نشود یک خطا گزارش می‌دهد:: + + >>> L = ['s', 'b', 'c', 'a', 's', 'b'] + + >>> L.index('b') + 1 + + >>> L.index('b', 2) + 5 + + >>> L.index('z') + Traceback (most recent call last): + File "", line 1, in + ValueError: 'z' is not in list + +* ``(count(x`` - تعداد وقوع شی ``x`` را در لیست مورد نظر برمی‌گرداند:: + + >>> L = ['a', 'b', 'c', 'a', 'a', 'b'] + + >>> L.count('a') + 3 + >>> L.count(5) + 0 + +* ``()clear`` - تمام عضوهای لیست مورد نظر را حذف می‌کند. عملکرد این متد معادل دستور ``[:]del L`` می‌باشد:: + + >>> L = [0, 1, 2, 3, 4, 5] + + >>> L.clear() + >>> L + [] + + :: + + >>> L = [0, 1, 2, 3, 4, 5] + + >>> del L[:] + >>> L + [] + + +* ``()reverse`` - عضوهای لیست مورد نظر را وارونه می‌کند:: + + >>> L = ['a', 'b', 'c', 'd'] + + >>> L.reverse() + >>> L + ['d', 'c', 'b', 'a'] + +* ``()sort`` - عضوهای یک لیست را مرتب می‌کند:: + + >>> L = [4, 6, 2, 1, 5, 0, 3] + + >>> L.sort() + >>> L + [0, 1, 2, 3, 4, 5, 6] + + :: + + >>> L = ['g', 'e', 'h', 'f', 'd'] + + >>> L.sort() + >>> L + ['d', 'e', 'f', 'g', 'h'] + + این متد در حالت پیش‌فرض به صورت صعودی اقدام به مرتب سازی می‌کند ولی می‌توان با فرستادن مقدار ``True`` به آرگومان اختیاری ``reverse``، شیوه آن را به نزولی تغییر داد:: + + >>> L = [4, 6, 2, 1, 5, 0, 3] + + >>> L.sort(reverse=True) + >>> L + [6, 5, 4, 3, 2, 1, 0] + + متد ``()sort`` آرگومان اختیاری دیگری نیز با نام ``key`` دارد که می‌توان با ارسال یک تابع تک آرگومانی به آن عمل دلخواهی را بر روی تک تک عضوهای لیست مورد نظر، پیش از مقایسه و مرتب‌سازی به انجام رساند. البته باید توجه داشت که تنها می‌بایست نام تابع به آرگومان متد فرستاده شود و نه الگو کامل آن؛ برای مثال تابع با الگو ``(func(x`` باید به صورت ``key=func`` فرستاده شود. چنانچه آرگومان ``key`` فرستاده شود، این متد عضوهای لیست را به تابع تعیین شده می‌فرستد و در انتها خروجی آن‌ها را برای عمل مرتب‌سازی در نظر می‌گیرد. به نمونه کد پایین توجه نمایید:: + + >>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h'] + + >>> L.sort() + >>> L + ['B', 'D', 'G', 'a', 'c', 'e', 'f', 'h'] + + *همانطور که مشاهده می‌شود حروف بزرگ در ابتدای لیست مرتب شده قرار گرفته‌اند؛ در واقع حروف بزرگ موجود در لیست به مقدار کوچکتری ارزیابی شده‌اند که اگر به کد اَسکی این حروف توجه نمایید متوجه علت این ارزیابی خواهید شد.* برای رفع این مشکل می‌توان پیش از آنکه عمل مقایسه برای مرتب‌سازی انجام پذیرد با فراخونی تابعی بر روی عضوهای لیست، تمام حروف را به بزرگ یا کوچک تبدیل نماییم تا حروف در سطح یکسانی برای مقایسه قرار بگیرند:: + + >>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h'] + + >>> L.sort(key=str.lower) + >>> L + ['a', 'B', 'c', 'D', 'e', 'f', 'G', 'h'] + + در نمونه کد بالا ``str.lower`` به چه معنی است؟ + + در درس پیش با کلاس ``()str`` که از آن برای ایجاد شی رشته استفاده می‌شد آشنا شدیم و با برخی از متدهای آن که برای یک شی رشته در دسترس بود (مانند: ``()join``) نیز کار کردیم. در آینده توسط درس مربوط به کلاس‌ها خواهیم آموخت که می‌توان با استفاده از نام کلاس و بدون ایجاد شی، متدهای داخل آن را فراخوانی نمود؛ در اینجا نیز همین اتفاق افتاده است و ``(lower(s`` متدی تک آرگومانی داخل کلاس ``str`` می‌باشد که توسط نام این کلاس فراخوانی شده است. + + :: + + >>> str + + + >>> str.lower + + + >>> dir(str) + ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] + + + .. tip:: + با استفاده از تابع آماده ``()dir`` [`اسناد پایتون `__] می‌توانیم لیستی از تمام صفت‌ها و متدهای در دسترس یک شی را دریافت نماییم. + + + به جای متد ``()sort`` می‌توان از تابع آماده ``()sorted`` [`اسناد پایتون `__] نیز با همین توضیح استفاده کرد:: + + >>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h'] + + >>> sorted(L) + ['B', 'D', 'G', 'a', 'c', 'e', 'f', 'h'] + + >>> sorted(L, key=str.lower, reverse=True) + ['h', 'G', 'f', 'e', 'D', 'c', 'B', 'a'] + + +.. _python-stack-with-list: + +ایجاد پشته +~~~~~~~~~~~~~~~~~ + +«پشته» (`Stack `_) ساختاری برای نگهداری موقت داده‌ها می‌باشد به شکلی که آخرین داده‌ای که در آن قرار می‌گیرد نخستین داده‌ای خواهد بود که خارج می‌گردد؛ این شیوه سازمان‌دهی LIFO یا Last In, First Out خوانده می‌شود. پشته تنها از دو عمل (یا متد) پشتیبانی می‌کند: **push** که داده‌ای را بالای تمام داده‌های موجود در آن قرار می‌دهد و **pop** که بالاترین داده را از آن خارج می‌کند. + +ساختار پشته را می‌توان به سادگی با استفاده از نوع لیست در پایتون پیاده‌سازی کرد؛ به این صورت که برای یک شی لیست متد ``()append`` معادل عمل push و متد ``()pop`` نیز معادل عمل pop خواهد بود:: + + >>> stack = [] + + >>> stack.append(1) + >>> stack.append(2) + >>> stack.append(3) + + >>> stack + [1, 2, 3] + + >>> stack.pop() + 3 + >>> stack.pop() + 2 + + >>> stack + [1] + + + +توپِل +------ + +نوع «**توپِل**» (Tuple) همانند نوع ``list`` است تنها با این تفاوت که تغییرپذیر **نیست** (بنابراین به نسبت مقدار حافظه کمتری مصرف می‌کند) و عضوهای آن درون پرانتز ``()`` قرار داده می‌شوند:: + + >>> t = (1, 2, 3) + >>> type(t) + + + >>> t + (1, 2, 3) + >>> print(t) + (1, 2, 3) + + >>> import sys + >>> sys.getsizeof(t) + 72 + +:: + + >>> t = () # An empty tuple + >>> t + () + +در انتهای شی توپِل تک عضوی می‌بایست یک نماد کاما قرار داد؛ به مانند: ``(,1)``. از آنجا که از پرانتز در عبارت‌ها نیز استفاده می‌شود؛ با این کار مفسر پایتون یک شی توپِل را از عبارت تشخیص می دهد:: + + + >>> (4 + 1) + 5 + + >>> a = (1) + >>> a + 1 + >>> type(a) + + +:: + + >>> t = (1,) + >>> t + (1,) + >>> type(t) + + + +برای ایجاد شی توپِل حتی می‌توان از گذاردن پرانتز صرف نظر کرد و تنها اشیا (یا عبارت‌ها) را با کاما از یکدیگر جدا نمود:: + + >>> 5, + (5,) + +:: + + >>> 1, 2 , 'a', 'b' + (1, 2, 'a', 'b') + +:: + + >>> t = 'p', 'y' + >>> t + ('p', 'y') + +:: + + >>> 5 > 1, True == 0 , 7-2 + (True, False, 5) + + + +.. note:: + نوع توپِل به دلیل تغییر ناپذیر بودن، نسبت به نوع لیست در مصرف حافظه بهینه‌تر می‌باشد؛ بنابراین بهتر است در مواقعی که نیاز به تغییر خاصی در داده‌ها نیست از این نوع استفاده شود. همچنین در مواقعی که نباید داده‌ها تغییر کنند، استفاده از شی توپِل به جای لیست می‌تواند از آن‌ها در برابر تغییر محافظت کند. + + +به دلیل شباهت‌های بسیار شی توپِل به شی لیست از ارایه توضیحات تکراری اجتناب کرده و تنها به ذکر چند مثال در ارتباط با نوع توپِل می‌پردازیم:: + + >>> ('a', 'b', 'c') + (1 , 2, 3) + ('a', 'b', 'c', 1, 2, 3) + + >>> ('python', 0) * 3 + ('python', 0, 'python', 0, 'python', 0) + +:: + + >>> t = ('p', 'y', [1, 2, 3], 5) + + >>> 'p' in t + True + >>> 2 not in t + True + >>> [1, 2, 3] not in t + False + +:: + + >>> (1, 'python') == (1, 'python') + True + >>> (1, 'python') == (1, 'PYTHON') + False + +:: + + >>> t1 = (1, 2, 3) + >>> t2 = t1 + >>> t2 == t1 + True + >>> t2 is t1 + True + + >>> t1 = (1, 2, 3) + >>> t2 = (1, 2, 3) + >>> t2 == t1 + True + >>> t2 is t1 + False + +:: + + >>> t = ('p', 'y', [1, 2, 3], 5) + + >>> t[0] + 'p' + >>> t[-1] + 5 + >>> t[:2] + ('p', 'y') + >>> t[2] + [1, 2, 3] + >>> t[2][1] + 2 + + >>> t[0] = 'j' + Traceback (most recent call last): + File "", line 1, in + TypeError: 'tuple' object does not support item assignment + +:: + + >>> t = ('p', 'y', [1, 2, 3], 5) + + >>> len(t) + 4 + >>> len(t[2]) + 3 + +به دلیل ساختار ارجاعی بین اشیا در پایتون که توسط تصاویر بخش لیست نیز نمایش داده شد؛ اشیا تغییر پذیر درون شی توپِل، ویژگی‌های خود را داشته و همچنان تغییر پذیر خواهند بود:: + + >>> t = ('p', 'y', [1, 2, 3], 5) + + >>> t[2][1] = 8 + >>> t + ('p', 'y', [1, 8, 3], 5) + +همچنین به نمونه کدهای پایین در مورد Unpacking توجه نمایید:: + + >>> a, *b = (1.1, 2.2, 3.3, 4.4) + + >>> a + 1.1 + >>> b + [2.2, 3.3, 4.4] + +:: + + >>> a, *b, c = (1.1, 2.2, 3.3, 4.4) + + >>> a + 1.1 + >>> b + [2.2, 3.3] + >>> c + 4.4 + +:: + + >>> a, *b = [1.1, 2.2, (3.3, 4.4)] + + >>> a + 1.1 + >>> b + [2.2, (3.3, 4.4)] + +:: + + >>> a, *b, c = [1.1, 2.2, (3.3, 4.4)] + + >>> a + 1.1 + >>> b + [2.2] + >>> c + (3.3, 4.4) + +:: + + >>> a, *b, c = (1.1, 2.2, (3.3, 4.4)) + + >>> a + 1.1 + >>> b + [2.2] + >>> c + (3.3, 4.4) + +*حتما متوجه شده‌اید که عضوهای دنباله تنها با نوع لیست به نام نشانه‌گذاری شده انتساب داده می‌شود.* + + +در هنگام انتساب متغیر توپِل به موضوع کپی نشدن اشیا تغییر پذیر توجه داشته باشید و در صورت نیاز از ماژول ``copy`` استفاده نمایید:: + + >>> t1 = ('p', 'y', [1, 2, 3], 5) + + >>> t2 = t1 # No Copy + + >>> t1[2][1] = 8 + + >>> t1 + ('p', 'y', [1, 8, 3], 5) + >>> t2 + ('p', 'y', [1, 8, 3], 5) + +:: + + >>> t1 = ('p', 'y', [1, 2, 3], 5) + + >>> import copy + >>> t2 = copy.deepcopy(t1) # Deep Copy + + >>> t1[2][1] = 8 + + >>> t1 + ('p', 'y', [1, 8, 3], 5) + >>> t2 + ('p', 'y', [1, 2, 3], 5) + + + +همانند شی لیست؛ شی توپِل نیز به دو متد ``()index`` و ``()count`` دسترسی دارد - این موضوع با استفاده از تابع ``()dir`` قابل بررسی است:: + + >>> t = ('s', 'b', 'c', 'a', 's', 'b') + +:: + + >>> dir(t) + ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index'] + +:: + + >>> t.index('b') + 1 + + >>> t.index('b', 2) + 5 + + >>> t.index('z') + Traceback (most recent call last): + File "", line 1, in + ValueError: tuple.index(x): x not in tuple + +:: + + >>> t.count('a') + 3 + >>> t.count(5) + 0 + +استفاده از راهنما را که فراموش نکرده‌اید؟!:: + + >>> t = ('s', 'b', 'c', 'a', 's', 'b') + + >>> help(t.index) + + Help on built-in function index: + + index(...) method of builtins.tuple instance + T.index(value, [start, [stop]]) -> integer -- return first index of value. + Raises ValueError if the value is not present. + (END) + + +هر زمان که نیاز به اِعمال تغییر در شی توپِل باشد؛ می‌توان شی مورد نظر را به صورت موقت به یک شی لیست تبدیل کرد. در این حالت می‌توان از ویژگی و متدهای شی لیست بهره برد و تغییرات دلخواه را اعمال کرد و در نهایت با یک تبدیل نوع دیگر دوباره به شی توپِل بازگشت. برای این منظور می‌توان با استفاده از کلاس ``()list`` یک دنباله - در اینجا یک شی توپِل - را به شی لیست تبدیل کرد و در طرف دیگر توسط کلاس ``()tuple`` نیز یک دنباله - در اینجا یک شی لیست - را به شی توپِل تبدیل نمود:: + + >>> t = (1, 2, 3) + >>> type(t) + + + >>> L = list(t) + >>> type(L) + + >>> L + [1, 2, 3] + + >>> L.insert(0, 'python') + >>> L + ['python', 1, 2, 3] + + >>> t = tuple(L) + >>> t + ('python', 1, 2, 3) + + +البته در مواقعی که می‌خواهید عضوهای درون یک شی توپِل را مرتب (Sort) کنید، نیازی به تبدیل نوع لیست نمی‌باشد و می‌توانید از تابع ``()sorted`` استفاده نمایید؛ این تابع مطابق آنچه که پیش از این معرفی شد یک شی توپِل را می‌گیرد و یک شی لیست با همان عضوها اما مرتب شده را برمی‌گرداند:: + + >>> t = ('a', 'D', 'c', 'B', 'e', 'f', 'G', 'h') + + >>> sorted(t, key=str.lower, reverse=True) + ['h', 'G', 'f', 'e', 'D', 'c', 'B', 'a'] + + +کلاس ``()tuple`` بدون آرگومان یک شی توپِل خالی را ایجاد می‌کند:: + + >>> t = tuple() + >>> t + () + >>> type(t) + + +| + +---- + +: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..74b50d4 --- /dev/null +++ b/source/lessons/l08-set-and-dict-in-python.rst @@ -0,0 +1,809 @@ +.. role:: emoji-size + +.. meta:: + :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامه‌نویسی پایتون - درس هشتم: ساختمان‌های داده در پایتون، set و dict + :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, ساختمان‌های داده در پایتون, set در پایتون, dict در پایتون + + + +.. _lesson-08.2: + +درس ۰۸: ساختمان‌های داده در پایتون: 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 + +---- + + +.. _python-dict: + +دیکشنری +--------- + +یکی دیگر از انواع ساختمان‌های داده در پایتون «**دیکشنری**» (Dictionary) می‌باشد که با نام کوتاه شده ``dict`` ارایه شده است. اشیا نوع دیکشنری با استفاده از نماد آکولاد ``{ }`` معرفی‌ می‌شوند و هر داده در آن به شکل یک جفت «**کلید:مقدار**» (key:value) ذخیره می‌گردد. از این نوع شی با عنوان شی mapping (نگاشت) پایتون نیز یاد می‌شود چرا که در این نوع هر شی «کلید» به یک شی «مقدار» map یا نگاشت داده می‌شود. شی دیکشنری **دنباله نیست** و هر عضو آن به جای اندیس با استفاده از کلید دستیابی می‌شود. دیکشنری در پایتون **تغییر پذیر** است و شی «مقدار» می‌تواند از هر نوعی باشد حتی یک شی دیکشنری دیگر ولی شی «کلید» تنها می‌بایست از انواع «تغییرناپذیر» انتخاب شود و باید توجه داشت که تمام «کلید»‌های یک شی دیکشنری می‌بایست «**یکتا**» (Unique) باشند. از **نسخه 3.7 پایتون**، دیکشنری قابلیت حفظ ترتیب عناصر خود را نیز دارد یا به اصطلاح Ordered است. + +:: + + >>> 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 + + +برای ایجاد شی دیکشنری می‌توان از کلاس ``()dict`` [`اسناد پایتون `__] نیز استفاده نمود:: + + + >>> d = dict(one=1, two=2, three=3) + + >>> d + {'two': 2, 'one': 1, 'three': 3} + >>> d['one'] + 1 + +توجه داشته باشید که عضوهای شی دیکشنری از طریق آرگومان‌ها و به شکل «**کلید=مقدار**» به کلاس فرستاده می‌شوند و در این حالت برای انتخاب کلیدها باید قوانین انتخاب نام در پایتون را رعایت نماییم؛ برای مثال کلیدی که با عدد شروع شود مجاز نمی‌باشد. + + + + +ساختار نوع دیکشنری مشابه «جدول درهم‌سازی» (`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', 'age': 40, 'job': 'unemployed'} + + +با استفاده از دستوری مشابه ``[del dic[key`` نیز می‌توان یک عضو شی دیکشنری را حذف کرد:: + + >>> d = {'name': 'Jhon', 'age': 40, 'job': 'unemployed'} + + >>> del d['job'] + >>> d + {'name': 'Jhon', 'age': 40} + + +امکانی برای تغییر کلیدها وجود ندارد مگر آنکه عضو مورد نظر را حذف کرده و یک عضو جدید (همان مقدار ولی با کلیدی جدید) اضافه نمایید:: + + >>> d = {'name': 'Jhon', 'age': 40, 'job': 'unemployed'} + + >>> d['occupation'] = d['job'] + >>> del d['job'] + + >>> d + {'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'} + + +.. _python-dict-operators: + +عملگرها برای دیکشنری +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +عملگرهای ``+`` و ``*`` برای اشیا دیکشنری تعریف **نشده‌اند**. + +از عملگرهای عضویت می‌توان برای بررسی وجود یک **کلید** در شی دیکشنری استفاده کرد:: + + >>> 'job' in {'name': 'Bob', 'age': 40} + False + + >>> 'job' not in {'name': 'Bob', 'age': 40} + True + +در مورد عملکرد عملگر برابری ``==`` و عملگرهای هویت (``is`` و ``is not``) صحبت شده است؛ این عملگرها برای اشیا دیکشنری نیز کاربرد دارند. + + +.. _python-dict-copy: + +کپی کردن +~~~~~~~~~~~~~~~~~~ + +همانطور که گفته شد شی دیکشنری از انواع «تغییر پذیر» پایتون است و همان توضیحاتی که در مورد شی لیست بیان شد؛ در اینجا هم درست است و گاهی نیاز می‌شود که از ماژول ``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']} + + +.. _python-convert-to-dict: + +تبدیل به شی دیکشنری +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +برای تبدیل دیگر اشیا به نوع دیکشنری یا در کل ایجاد شی دیکشنری از کلاس ``()dict`` [`اسناد پایتون `__] استفاده می‌شود. + + +برای تبدیل اشیا دنباله به مانند لیست و توپِل به دیکشنری می‌بایست از ساختار تودرتو استفاده کرد، به گونه‌ای که هر عضو این ساختمان‌ها خود شامل دو عضو باشد:: + + >>> 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'} + >>> + + +البته می‌توان از یک مقدار پیش‌فرض نیز برای تبدیل نوع سریع آن‌ها به روش زیر بهره برد:: + + + >>> 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'] + + >>> 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`` استفاده خواهیم کرد. + + +.. _python-dict-methods: + +برخی از متدهای کاربردی یک شی دیکشنری +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``()items`` [`اسناد پایتون `__] تمام عضوهای شی را برمی‌گرداند - ``()values`` [`اسناد پایتون `__] تمام مقدارهای موجود در شی را بر می‌گرداند - ``()keys`` [`اسناد پایتون `__] تمام کلیدهای موجود در شی را بر می‌گرداند:: + + >>> 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]) + + +* ``()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'} + + + + +.. _python-set: + + +مجموعه +-------- + +«**مجموعه**» (Set) از انواع «بدون ترتیب» (Unordered) و «تغییر پذیر» (Mutable) پایتون است که برابر مفهوم مجموعه در ریاضیات می‌باشد. **هر عضو مجموعه می‌بایست یکتا و یکی از انواع «تغییر ناپذیر» باشد**. نوع مجموعه یا ``set`` را می‌توان با استفاده از کلاس ``()set`` [`اسناد پایتون `__] یا تنها با استفاده از نماد آکولاد ``{ }`` ایجاد کرد:: + + + >>> 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 = {} + >>> type(a) + + + >>> b = set() + >>> type(b) + + + >>> b + set() + + +از تابع ``()len`` می‌توان برای به دست آوردن تعداد عضوهای یک شی مجموعه نیز استفاده کرد:: + + >>> s = {1, 2, 3, 4, 5} + >>> len(s) + 5 + + +.. _python-set-operators: + +عملگرها برای مجموعه +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +تعدادی از عملگرها هستند که برای اشیا مجموعه تعریف خاصی پیدا می‌کنند؛ در حالی که در مورد اشیا دیگر چنین رفتاری ندارند. این عملگرها در واقع پیاده‌سازی تعریف مشخصی در مفهوم ریاضی مجموعه‌ها هستند: + +* ``|`` اجتماع (Union): مانند ``A | B`` که حاصل آن مجموعه‌ای می‌باشد که تمام عضوهای مجموعه ``A`` و مجموعه ``B`` را داشته باشد و هیچ عضو اضافه دیگری نداشته باشد:: + + >>> A = {'u', 'v', 'w', 'x', 'y', 'z'} + >>> B = {'q', 'r', 's', 't', 'u', 'v', 'w'} + + >>> A | B + {'y', 's', 'x', 'u', 'r', 'z', 't', 'w', 'v', 'q'} + +* ``&`` اشتراک (Intersection): مانند ``A & B`` که حاصل آن مجموعه‌ای می‌باشد که تنها شامل عضوهایی است که هم در مجموعه ``A`` هستند و هم در مجموعه ``B``:: + + >>> A & B + {'v', 'u', 'w'} + + +* ``-`` تفاضل (Difference): مانند ``A - B`` که حاصل آن مجموعه‌ای می‌باشد که تنها شامل عضوهایی از مجموعه ``A`` است كه در مجموعه ``B`` نيستند:: + + >>> A - B + {'y', 'z', 'x'} + + +* ``^`` تفاضل متقارن (Symmetric difference): مانند ``A ^ B`` که حاصل آن مجموعه‌ای می‌باشد که برابر اجتماع ِ تفاضل ``A`` از ``B`` و تفاضل ``B`` از ``A`` می‌باشد یعنی: ``(A-B) | (B-A)``:: + + >>> A ^ B + {'y', 'z', 's', 'q', 'x', 'r', 't'} + + :: + + >>> (A-B) | (B-A) + {'y', 'r', 'z', 't', 's', 'x', 'q'} + + + تفاضل متقارن را می‌توان به صورت پایین نیز تعریف کرد:: + + >>> (A|B) - (B&A) + {'y', 'x', 'r', 'z', 't', 's', 'q'} + +* ``>`` زیرمجموعه (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 + + +.. _python-set-methods: + +برخی از متدهای کاربردی یک شی مجموعه +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +* ``()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' + + +.. _python-frozenset: + +frozenset +~~~~~~~~~~~~~ + +همانطور که پیش از این بیان شد مجموعه یک شی «تغییر پذیر» است با عضوهای «تغییر ناپذیر» و به دلیل همین تغییر پذیری است که می‌توانیم به سادگی توسط متدهایش، عضوی به آن افزوده یا حذف نماییم. **”frozenset“** یک نوع جدید مجموعه است. همانگونه که می‌توانیم یک شی توپِل را معادل یک شی لیست تغییر ناپذیر تصویر کنیم؛ frozenset را نیز می‌توان **یک شی مجموعه تغییر ناپذیر** تصور کرد. نوع ``frozenset`` همان نوع ``set`` است، با تمام ویژگی‌های آن به غیر از تغییر پذیری که با استفاده از کلاس ``()frozenset`` ایجاد می‌گردد: + +:: + + >>> 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'] + + +دسته‌بندی +----------- + +اکنون با انواع داده و نیز ساختمان‌های داده متداول در پایتون آشنا شده‌اید. در این بخش به منظور جمع‌بندی، به دسته‌بندی این اشیا خواهیم پرداخت: + + +* انواع عددی (Numeric Types): + + .. code-block:: html + :linenos: + + - int + - float + - complex + - Decimal + - Fraction + - bool + +* انواع دنباله (Sequence Types): + + .. code-block:: html + :linenos: + + - str + - bytes + - bytearray + - tuple + - list + +* انواع تغییر ناپذیر (Immutable Types): + + .. code-block:: html + :linenos: + + - int + - float + - complex + - Decimal + - Fraction + - bool + - str + - bytes + - tuple + - frozenset + + +* انواع تغییر پذیر (Mutable Types): + + .. code-block:: html + :linenos: + + - bytearray + - list + - dict + - set + +* انواع نگاشت (Mapping Types): + + .. code-block:: html + :linenos: + + - dict + +* انواع مجموعه (Set Types): + + .. code-block:: html + :linenos: + + - set + - frozenset + + +* برخی دیگر: + + .. code-block:: html + :linenos: + + - zip + - NoneType + + +| + +---- + +:emoji-size:`😊` امیدوارم مفید بوده باشه + + diff --git a/source/lessons/l08.rst b/source/lessons/l08.rst deleted file mode 100644 index 60b80f5..0000000 --- a/source/lessons/l08.rst +++ /dev/null @@ -1,1885 +0,0 @@ -.. role:: emoji-size - -.. meta:: - :description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش انواع داده در پایتون، آموزش انواع لیست (list)، تاپل (tuple)، دیکشنری (dict) در پایتون، دسته بندی انواع داده در پایتون - :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, انواع شی در پایتون, انواع داده در پایتون, پایتون - - -درس ۰۸: انواع داده یا شی در پایتون: set ،dict ،tuple ،list و None -==================================================================================== - -.. figure:: /_static/pages/08-python-built-in-data-types-2.jpg - :align: center - :alt: انواع داده یا شی در پایتون: set ،dict ،tuple، list و None - :class: page-image - - Photo by `Natalia Y `__ - - -پایتون هر «نوع داده» (Data Type) را توسط یک کلاس ارایه می‌دهد؛ بنابراین هر داده یک نمونه یا یک شی از کلاسی مشخص است. هر چند برنامه‌نویس نیز می‌تواند با تعریف کلاس، نوع دلخواه خود را داشته باشد ولی در این درس می‌خواهیم درباره آن بخشی از انواع داده یا انواع شی‌ (Object Types) که به شکل آماده (Built-in) در اختیار مفسر زبان پایتون قرار داده شده است صحبت کنیم. - -این درس در ادامه درس پیش به بررسی برخی از انواع دیگر پایتون به مانند «لیست»، «تاپل»، «دیکشنری» و «مجموعه» می‌پردازد. - - - -:emoji-size:`✔` سطح: مقدماتی - ----- - -.. contents:: سرفصل‌ها - :depth: 2 - ----- - - -لیست ------- - -نوع «**لیست**» (List) انعطاف‌ پذیرترین نوع آماده در پایتون می‌باشد. این نوع همانند رشته یک «**دنباله**» (Sequence) بوده ولی برخلاف آن یک نوع «**تغییر پذیر**» (Mutable) است. شی لیست با استفاده از کروشه ``[ ]`` ایجاد می‌گردد و می‌تواند عضوهایی - **با هر نوع** - داشته باشد که توسط کاما ``,`` از یکدیگر جدا می‌شوند؛ نوع لیست در واقع محلی برای نگهداری اشیا گوناگون است:: - - >>> L = [1, 2, 3] - >>> type(L) - - - >>> L - [1, 2, 3] - >>> print(L) - [1, 2, 3] - - >>> import sys - >>> sys.getsizeof(L) - 88 - -:: - - >>> L = [] # An empty list - >>> L - [] - - -عضوهای لیست می‌توانند از هر نوعی باشند؛ حتی یک لیست:: - - >>> L = [15, 3.14, 'string', [1, 2]] - - -شی لیست جزو انواع دنباله پایتون است و می‌توان عضوها را بر اساس اندیس موقعیت آن‌ها دستیابی نمود:: - - >>> L = [1, 2, 3] - >>> L[0] - 1 - >>> L[-1] - 3 - -و همچنین تعداد عضوهای هر شی لیست را توسط تابع ``()len`` [`اسناد پایتون `__] به دست آورد:: - - >>> L1 = [] - >>> len(L1) - 0 - - >>> L2 = ['python', 12.06] - >>> len(L2) - 2 - - >>> len(L2[0]) - 6 - - >>> L3 = ['a', [1, 2], 'b'] - >>> len(L3) - 3 - >>> len(L3[1]) - 2 - - - - -چنانچه یک دنباله جزو عضوهای شی لیست باشد، با استفاده از الگو ``[seq[i][j`` می‌توان عضوهای آن را نیز دستیابی نمود که در آن ``i`` اندیسی است که به یک عضو شی لیست اشاره دارد و ``j`` نیز اشاره به اندیس داخلی عضو ``i`` دارد؛ این الگو به همین شیوه می‌تواند ادامه یابد:: - - >>> L = ['python', 2.56] - >>> L[0] - 'python' - >>> L[0][:2] - 'py' - - >>> L = ['python', 2.56, [128, ['a', 'z']]] - >>> L[2][1][0] - 'a' - - -یکی از مثال‌های رایج شی لیست‌، شبیه‌سازی ساختار ماتریس (`Matrix `_) است:: - - >>> L = [[1, 2, 3], - ... [4, 5, 6], - ... [7, 8, 9]] - >>> - - >>> L - [[1, 2, 3], [4, 5, 6], [7, 8, 9]] - - >>> L[0][1] - 2 - - - - -شی لیست جزو انواع Mutable پایتون است و می‌توان عضوهای آن را تغییر داد؛ این تغییر می‌تواند به شکل حذف، درج عضو جدید یا جایگزین کردن یک یا چند عضو باشد. پایتون متدهای کاربردی زیادی برای دستکاری و تغییر شی لیست دارد که در ادامه به آن‌ها نیز خواهیم پرداخت ولی در این بخش می‌خواهیم به بررسی چگونگی ایجاد تغییر با استفاده از عملگر انتساب بپردازیم: - - -* جایگزین کردن:: - - >>> L = [1, 2, 3] - - >>> L[1] = 'py' - >>> L - [1, 'py', 3] - - :: - - >>> L = [1, 2, 3, 4, 5, 6] - - >>> L[:2] = [0, 0] - >>> L - [0, 0, 3, 4, 5, 6] - -* درج کردن - ``i`` در الگو ``[seq[i:i`` به موقعیتی از شی ``seq`` اشاره دارد که می‌خواهیم درج در آن نقطه انجام شود؛ در این شیوه توجه داشته باشید که شی‌ای که می‌خواهید درون لیست درج کنید می‌بایست یک دنباله باشد:: - - >>> L = [0, 1, 5, 6] - - >>> L[2:2] = [2, 3, 4] - >>> L - [0, 1, 2, 3, 4, 5, 6] - - >>> L[0:0] = 'abc' - >>> L - ['a', 'b', 'c', 0, 1, 2, 3, 4, 5, 6] - - >>> L[3:3] = ['d', [-2, -1]] - >>> L - ['a', 'b', 'c', 'd', [-2, -1], 0, 1, 2, 3, 4, 5, 6] - - -* حذف کردن - کافی است یک شی لیست خالی (``[]``) را به یک یا چند عضو از شی لیست مورد نظر انتساب دهیم:: - - >>> L = [0, 1, 2, 3, 4, 5, 6] - - >>> L[2:5] = [] - >>> L - [0, 1, 5, 6] - - -.. rubric:: دستور ``del`` - -با استفاده از دستور ``del`` [`اسناد پایتون `__] نیز می‌توان یک عضو یا یک تکه از شی لیست را حذف کرد:: - - >>> L = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - - >>> del L[2] - >>> L - ['a', 'b', 'd', 'e', 'f', 'g'] - - >>> del L[1:4] - >>> L - ['a', 'f', 'g'] - -همچنین می‌توانیم از این دستور برای حذف کامل یک متغیر استفاده نماییم. با حدف یک متغیر، ارجاع آن به شی نیز حذف می‌شود و چنانچه هیچ ارجاع دیگری به آن شی وجود نداشته باشد، شی‌ای که متغیر به آن ارجاع داشت نیز حذف می‌گردد:: - - >>> a = 5 - >>> a - 5 - - >>> del a - - >>> a - Traceback (most recent call last): - File "", line 1, in - NameError: name 'a' is not defined - -.. rubric:: انتساب چندگانه - -می‌توان یک شی لیست - یا در کل یک شی دنباله - را به تعدادی نام انتساب داد و متغیرهای جداگانه‌ای ایجاد نمود؛ این عمل **Unpacking** خوانده می‌شود. در این شرایط مفسر پایتون هر عضو دنباله را با حفظ ترتیب به یکی از نام‌ها انتساب می‌دهد که در حالت عادی می‌بایست تعداد نام‌ها با عضوهای دنباله برابر باشد:: - - >>> L = [1.1, 2.2, 3.3, 4.4] - - >>> a, b, c, d = L - - >>> a - 1.1 - >>> b - 2.2 - >>> c - 3.3 - >>> d - 4.4 - -:: - - >>> a, b = [1.1, 2.2, 3.3, 4.4] - Traceback (most recent call last): - File "", line 1, in - ValueError: too many values to unpack (expected 2) - -ولی می‌توان یکی از نام‌ها را توسط نماد ``*`` نشانه‌گذاری کرد؛ در این شرایط مفسر پایتون توازنی را بین عضوهای دنباله و نام‌ها ایجاد می‌کند که در این حالت تمام عضوهای اضافی - در قالب یک شی لیست - به نام نشانه‌گذاری شده انتساب داده می‌شود. البته باید توجه داشت که ترتیب عضوهای دنباله در هر شرایطی رعایت خواهد شد؛ به نمونه کدهای پایین توجه نمایید:: - - >>> L = [1.1, 2.2, 3.3, 4.4] - - >>> a, b, *c = L - - >>> a - 1.1 - >>> b - 2.2 - >>> c - [3.3, 4.4] - -:: - - >>> *a, b = [1.1, 2.2, 3.3, 4.4] - - >>> a - [1.1, 2.2, 3.3] - >>> b - 4.4 - -:: - - >>> a, *b, c = [1.1, 2.2, 3.3, 4.4] - - >>> a - 1.1 - >>> b - [2.2, 3.3] - >>> c - 4.4 - -:: - - >>> a, b, c, *d = [1.1, 2.2, 3.3, 4.4] - - >>> a - 1.1 - >>> b - 2.2 - >>> c - 3.3 - >>> d - [4.4] - - -.. rubric:: کپی کردن - -همانند دیگر اشیا می‌توان با انتساب یک متغیر موجود از شی لیست به یک نام جدید، متغیر دیگری از این نوع شی ایجاد کرد. البته همانطور که پیش‌تر نیز بیان شده است؛ در این حالت شی کپی نمی‌گردد و تنها یک ارجاع جدید از این نام جدید به شی آن متغیر داده می‌شود. این موضوع با استفاده از تابع ``()id`` [`اسناد پایتون `__] قابل آزمودن است؛ خروجی این تابع برابر نشانی شی در حافظه می‌باشد و بدیهی است که دو مقدار id یکسان برای دو متغیر نشان از یکی بودن شی آن‌هاست:: - - >>> L1 = [1, 2, 3] - - >>> L2 = L1 - - >>> L2 - [1, 2, 3] - - >>> id(L1) - 140254551721800 - >>> id(L2) - 140254551721800 - - -عضوهای یک شی لیست تغییر پذیر هستند و باید توجه داشته باشیم اکنون که هر دو متغیر به یک شی اشاره دارند اگر توسط یکی از متغیرها، عضوهای شی مورد نظر تغییر داده شوند، مقدار مورد انتظار ما از شی متغیر دوم نیز تغییر خواهد کرد:: - - >>> L1 = [1, 2, 3] - - >>> L2 = L1 - - >>> L1[0] = 7 - - >>> L1 - [7, 2, 3] - >>> L2 - [7, 2, 3] - -اگر این موضوع را یک مشکل بدانیم برای رفع آن می‌توان از شی متغیر یک کپی ایجاد کرده و این کپی را به متغیر جدید نسبت دهیم؛ در این شرایط هر دو متغیر به اشیایی جداگانه در محل‌هایی متفاوت از حافظه اشاره خواهند داشت. در حالت عادی برای کپی کردن یک شی لیست نیاز به کار جدیدی نیست و می‌توان از اندیس گذاری ``[:]`` - به معنی تمامی عضوها - استفاده کرد:: - - >>> L1 - [7, 2, 3] - - >>> L2 = L1[:] - - >>> L1 - [7, 2, 3] - >>> L2 - [7, 2, 3] - - >>> id(L1) - 140254551721928 - >>> id(L2) - 140254551721800 - - >>> L1[0] = 5 - - >>> L1 - [5, 2, 3] - >>> L2 - [7, 2, 3] - -.. image:: /_static/l08-python-list-assignment-01.png - :align: center - -ولی اگر شی لیست مورد نظر عضوهایی از نوع لیست (یا هر نوع تغییر پذیر دیگر) داشته باشد، مشکل فوق همچنان برای این عضوها باقی است. به نمونه کد و تصویر پایین توجه نمایید:: - - >>> L1 = [1, 2, [7, 8]] - - >>> L2 = L1[:] - >>> L2 - [1, 2, [7, 8]] - - >>> L1[2][1] = 5 - - >>> L1 - [1, 2, [7, 5]] - >>> L2 - [1, 2, [7, 5]] - - >>> id(L1) - 140402644179400 - >>> id(L2) - 140402651379720 - - >>> id(L1[2]) - 140402644179080 - >>> id(L2[2]) - 140402644179080 - - - -.. image:: /_static/l08-python-list-assignment-02.png - :align: center - -در پایتون کپی شی به دو شیوه **«سطحی»** (Shallow Copy) و **«عمیق»** (Deep Copy) انجام می‌شود که به ترتیب توسط تابع‌های ``()copy`` و ``()deepcopy`` از درون ماژول ``copy`` در دسترس هستند [`اسناد پایتون `__]. در شیوه کپی سطحی همانند کاری که پیش از این انجام دادیدم - یعنی انتساب با استفاده از اندیس ``[:]`` - اشیا داخلی کپی نمی‌شوند و تنها یک ارجاع جدید به آن‌ها داده می‌شود؛ در حالی که توسط شیوه کپی عمیق از تمامی اشیا (تغییر پذیر) داخلی نیز یک کپی ایجاد می‌گردد:: - - >>> L1 = [1, 2, [7, 8]] - - >>> import copy - >>> L2 = copy.copy(L1) # Shallow Copy - - >>> L1[2][1] = 5 - - >>> L1 - [1, 2, [7, 5]] - >>> L2 - [1, 2, [7, 5]] - -:: - - >>> L1 = [1, 2, [7, 8]] - - >>> import copy - >>> L2 = copy.deepcopy(L1) # Deep Copy - - >>> L1[2][1] = 5 - - >>> L1 - [1, 2, [7, 5]] - >>> L2 - [1, 2, [7, 8]] - - >>> id(L1) - 140402651379656 - >>> id(L2) - 140402644179400 - - >>> id(L1[2]) - 140402644106312 - >>> id(L2[2]) - 140402651379080 - -.. rubric:: عملگرها برای لیست - -می‌توان از عملگرهای ``+`` (برای پیوند لیست‌ها) و ``*`` (برای تکرار عضوهای لیست) بهره برد:: - - >>> [1, 2] + [2, 3] + [3, 4] - [1, 2, 2, 3, 3, 4] - - >>> ['python'] * 3 - ['python', 'python', 'python'] - - -برای بررسی برابر بودن مقدار دو شی لیست مانند دیگر اشیا می‌توان از عملگر ``==`` استفاده کرد:: - - >>> [1, 'python'] == [1, 'python'] - True - - >>> [1, 'python'] == [1, 'PYTHON'] - False - -از عملگرهای عضویت هم می‌توان برای بررسی وجود شی‌ای درون لیست استفاده کرد:: - - >>> L = ['a', [1, 2]] - - >>> 'b' not in L - True - >>> 2 in L - False - >>> [1, 2] in L - True - -.. rubric:: تفاوت عملگرهای ``==`` و ``is`` - -نکته‌ای که در درس‌های پیش مطرح نشد، بیان تفاوت بین عملگر برابری و عملگر هویت است. پیش از ارایه توضیح به نمونه کد پایین توجه نمایید:: - - >>> a = 5 - >>> b = a - >>> a == b - True - >>> a is b - True - - >>> L1 = [1, 2, 3] - >>> L2 = L1 - >>> L1 == L2 - True - >>> L1 is L2 - True - - >>> L2 = L1[:] - >>> L1 == L2 - True - >>> L1 is L2 # False! - False - - -از درس پنجم به یاد داریم که هر شی در پایتون حاوی یک «شناسه» (identity)، یک «نوع» (type) و یک «مقدار» (value) است. عملگر ``==`` دو شی را از نظر یکسان بودن «مقدار» مورد بررسی قرار می‌دهد در حالی که عملگر ``is`` دو شی را از نظر یکسان بودن «شناسه» (خروجی تابع ``()id``) یا همان نشانی آن‌ها در حافظه مورد بررسی قرار می‌دهد. - -پیش از این هم بیان شده بود که مفسر پایتون برای صرفه‌جویی در زمان و حافظه از ساخت مجدد اشیا نوع «صحیح» و «رشته» کوچک موجود اجتناب می‌کند و تنها یک ارجاع جدید به آن‌ها می‌دهد. اما این موضوع در مورد اشیا دیگر درست نمی‌باشد و مفسر پایتون برای هر متغیری که برای این نوع اشیا تعریف می‌گردد یک شی جدید ایجاد می‌کند و به آن ارجاع می‌دهد:: - - >>> a = 5 - >>> b = 5 - >>> a == b - True - >>> a is b - True - - >>> m = 'python' - >>> n = 'python' - >>> m == n - True - >>> m is n - True - - >>> L1 = [1, 2, 3] - >>> L2 = [1, 2, 3] - >>> L1 == L2 - True - >>> L1 is L2 # False! - False - - -.. rubric:: تبدیل به شی لیست - -با استفاده از کلاس ``()list`` [`اسناد پایتون `__] می‌توان یک شی لیست ایجاد کرد یا اشیایی که از نوع دنباله هستند را به یک شی لیست تبدیل نمود:: - - >>> a = 'python' - >>> type(a) - - - >>> b = list(a) - >>> type(b) - - - >>> b - ['p', 'y', 't', 'h', 'o', 'n'] - -:: - - >>> L = list() - >>> L - [] - - - - -.. rubric:: متدهای کاربردی یک شی لیست - -شی لیست تغییر پذیر است و متدهای آن برخلاف شی رشته یک شی جدید تغییر یافته را برنمی‌گردانند بلکه تغییرات را بر روی همان شی ایجاد می‌کنند. - -* ``(append(x`` - شی ``x`` را به انتهای لیست مورد نظر اضافه می‌کند:: - - >>> L = [1, 2, 3] - - >>> L.append(4) - >>> L - [1, 2, 3, 4] - - >>> L.append(['a', 'b']) - >>> L - [1, 2, 3, 4, ['a', 'b']] - - عملکرد این متد (``(L.append(x``) همانند عمل ``[L + [x`` است:: - - >>> L = [1, 2, 3] - >>> L + [4] - [1, 2, 3, 4] - - -* ``(extend(s`` - عضوهای شی دنباله ``s`` را به انتهای لیست مورد نظر اضافه می‌کند:: - - >>> L = [1, 2, 3] - - >>> L.extend(['a', 'b']) - >>> L - [1, 2, 3, 'a', 'b'] - - :: - - >>> L = [1, 2, 3] - - >>> L.extend('py') - >>> L - [1, 2, 3, 'p', 'y'] - - -* ``(insert(i, x`` - یک عضو جدید (مانند ``x``) را در موقعیتی از لیست با اندیس دلخواه (مانند ``i``) قرار می‌دهد:: - - >>> L = [1, 2, 3] - - >>> L.insert(0, 'python') - >>> L - ['python', 1, 2, 3] - -* ``(remove(x`` - در لیست مورد نظر از سمت چپ به دنبال شی‌ ``x`` می‌گردد و نخستین مورد یافت شده را از لیست حذف می‌کند. چنانچه هیچ عضو برابری با شی ``x`` یافت نشود یک خطا گزارش می‌دهد:: - - >>> L = [1, 2, 3, 5, 2 , 6 , 1] - - >>> L.remove(2) - >>> L - [1, 3, 5, 2, 6, 1] - - >>> L.remove(0) - Traceback (most recent call last): - File "", line 1, in - ValueError: list.remove(x): x not in list - - .. note:: - در مواردی که می‌خواهید اندیس خاصی از لیست را حذف نمایید؛ از دستور ``del`` استفاده کنید. - - -* ``([pop([i`` - عضو متناظر با اندیس ``i`` را از لیست حذف و به عنوان خروجی برمی‌گرداند. چنانچه اندیس به متد فرستاده نشود به صورت پیش‌فرض **آخرین عضو** از لیست مورد نظر را حذف و برمی‌گرداند:: - - >>> L = ['a', 'b', 'c', 'd'] - - >>> L.pop(2) - 'c' - >>> L - ['a', 'b', 'd'] - - >>> L.pop() - 'd' - >>> L - ['a', 'b'] - - .. note:: - نماد ``[ ]`` در الگو متدها تنها روشی برای بیان اختیاری بودن عبارت درون آن می‌باشد و جزیی از متد نیست. - - -* ``([index(x[, n`` - در لیست مورد نظر از سمت چپ به دنبال شی ``x`` می‌گردد و اندیس نخستین مورد یافت شده را برمی‌گرداند. این متد یک آرگومان اختیاری (``n``) نیز دارد که به کمک آن می‌توان تعیین نمود اندیس چندمین مورد یافت شده برگردانده شود. چنانچه هیچ عضو برابری با شی ``x`` یافت نشود یک خطا گزارش می‌دهد:: - - >>> L = ['s', 'b', 'c', 'a', 's', 'b'] - - >>> L.index('b') - 1 - - >>> L.index('b', 2) - 5 - - >>> L.index('z') - Traceback (most recent call last): - File "", line 1, in - ValueError: 'z' is not in list - -* ``(count(x`` - تعداد وقوع شی ``x`` را در لیست مورد نظر برمی‌گرداند:: - - >>> L = ['a', 'b', 'c', 'a', 'a', 'b'] - - >>> L.count('a') - 3 - >>> L.count(5) - 0 - -* ``()clear`` - تمام عضوهای لیست مورد نظر را حذف می‌کند. عملکرد این متد معادل دستور ``[:]del L`` می‌باشد:: - - >>> L = [0, 1, 2, 3, 4, 5] - - >>> L.clear() - >>> L - [] - - :: - - >>> L = [0, 1, 2, 3, 4, 5] - - >>> del L[:] - >>> L - [] - - -* ``()reverse`` - عضوهای لیست مورد نظر را وارونه می‌کند:: - - >>> L = ['a', 'b', 'c', 'd'] - - >>> L.reverse() - >>> L - ['d', 'c', 'b', 'a'] - -* ``()sort`` - عضوهای یک لیست را مرتب می‌کند:: - - >>> L = [4, 6, 2, 1, 5, 0, 3] - - >>> L.sort() - >>> L - [0, 1, 2, 3, 4, 5, 6] - - :: - - >>> L = ['g', 'e', 'h', 'f', 'd'] - - >>> L.sort() - >>> L - ['d', 'e', 'f', 'g', 'h'] - - این متد در حالت پیش‌فرض به صورت صعودی اقدام به مرتب سازی می‌کند ولی می‌توان با فرستادن مقدار ``True`` به آرگومان اختیاری ``reverse``، شیوه آن را به نزولی تغییر داد:: - - >>> L = [4, 6, 2, 1, 5, 0, 3] - - >>> L.sort(reverse=True) - >>> L - [6, 5, 4, 3, 2, 1, 0] - - متد ``()sort`` آرگومان اختیاری دیگری نیز با نام ``key`` دارد که می‌توان با ارسال یک تابع تک آرگومانی به آن عمل دلخواهی را بر روی تک تک عضوهای لیست مورد نظر، پیش از مقایسه و مرتب‌سازی به انجام رساند. البته باید توجه داشت که تنها می‌بایست نام تابع به آرگومان متد فرستاده شود و نه الگو کامل آن؛ برای مثال تابع با الگو ``(func(x`` باید به صورت ``key=func`` فرستاده شود. چنانچه آرگومان ``key`` فرستاده شود، این متد عضوهای لیست را به تابع تعیین شده می‌فرستد و در انتها خروجی آن‌ها را برای عمل مرتب‌سازی در نظر می‌گیرد. به نمونه کد پایین توجه نمایید:: - - >>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h'] - - >>> L.sort() - >>> L - ['B', 'D', 'G', 'a', 'c', 'e', 'f', 'h'] - - *همانطور که مشاهده می‌شود حروف بزرگ در ابتدای لیست مرتب شده قرار گرفته‌اند؛ در واقع حروف بزرگ موجود در لیست به مقدار کوچکتری ارزیابی شده‌اند که اگر به کد اَسکی این حروف توجه نمایید متوجه علت این ارزیابی خواهید شد.* برای رفع این مشکل می‌توان پیش از آنکه عمل مقایسه برای مرتب‌سازی انجام پذیرد با فراخونی تابعی بر روی عضوهای لیست، تمام حروف را به بزرگ یا کوچک تبدیل نماییم تا حروف در سطح یکسانی برای مقایسه قرار بگیرند:: - - >>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h'] - - >>> L.sort(key=str.lower) - >>> L - ['a', 'B', 'c', 'D', 'e', 'f', 'G', 'h'] - - در نمونه کد بالا ``str.lower`` به چه معنی است؟ - - در درس پیش با کلاس ``()str`` که از آن برای ایجاد شی رشته استفاده می‌شد آشنا شدیم و با برخی از متدهای آن که برای یک شی رشته در دسترس بود (مانند: ``()join``) نیز کار کردیم. در آینده توسط درس مربوط به کلاس‌ها خواهیم آموخت که می‌توان با استفاده از نام کلاس و بدون ایجاد شی، متدهای داخل آن را فراخوانی نمود؛ در اینجا نیز همین اتفاق افتاده است و ``(lower(s`` متدی تک آرگومانی داخل کلاس ``str`` می‌باشد که توسط نام این کلاس فراخوانی شده است. - - :: - - >>> str - - - >>> str.lower - - - >>> dir(str) - ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] - - - .. tip:: - با استفاده از تابع آماده ``()dir`` [`اسناد پایتون `__] می‌توانیم لیستی از تمام صفت‌ها و متدهای در دسترس یک شی را دریافت نماییم. - - - به جای متد ``()sort`` می‌توان از تابع آماده ``()sorted`` [`اسناد پایتون `__] نیز با همین توضیح استفاده کرد:: - - >>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h'] - - >>> sorted(L) - ['B', 'D', 'G', 'a', 'c', 'e', 'f', 'h'] - - >>> sorted(L, key=str.lower, reverse=True) - ['h', 'G', 'f', 'e', 'D', 'c', 'B', 'a'] - - -.. rubric:: ایجاد پشته - -«پشته» (`Stack `_) ساختاری برای نگهداری موقت داده‌ها می‌باشد به شکلی که آخرین داده‌ای که در آن قرار می‌گیرد نخستین داده‌ای خواهد بود که خارج می‌گردد؛ این شیوه سازمان‌دهی LIFO یا Last In, First Out خوانده می‌شود. پشته تنها از دو عمل (یا متد) پشتیبانی می‌کند: **push** که داده‌ای را بالای تمام داده‌های موجود در آن قرار می‌دهد و **pop** که بالاترین داده را از آن خارج می‌کند. - -ساختار پشته را می‌توان به سادگی با استفاده از نوع لیست در پایتون پیاده‌سازی کرد؛ به این صورت که برای یک شی لیست متد ``()append`` معادل عمل push و متد ``()pop`` نیز معادل عمل pop خواهد بود:: - - >>> stack = [] - - >>> stack.append(1) - >>> stack.append(2) - >>> stack.append(3) - - >>> stack - [1, 2, 3] - - >>> stack.pop() - 3 - >>> stack.pop() - 2 - - >>> stack - [1] - - - -تاپل ------- - -نوع «**تاپِل**» (Tuple) همانند نوع ``list`` است ولی با این تفاوت که تغییر پذیر **نیست** و عضوهای آن درون پرانتز ``()`` قرار داده می‌شوند:: - - >>> t = (1, 2, 3) - >>> type(t) - - - >>> t - (1, 2, 3) - >>> print(t) - (1, 2, 3) - - >>> import sys - >>> sys.getsizeof(t) - 72 - -:: - - >>> t = () # An empty tuple - >>> t - () - -در انتهای شی تاپل تک عضوی می‌بایست یک نماد کاما قرار داد؛ به مانند: ``(,1)``. از آنجا که از پرانتز در عبارت‌ها نیز استفاده می‌شود؛ با این کار مفسر پایتون یک شی تاپل را از عبارت تشخیص می دهد:: - - - >>> (4 + 1) - 5 - - >>> a = (1) - >>> a - 1 - >>> type(a) - - -:: - - >>> t = (1,) - >>> t - (1,) - >>> type(t) - - - -برای ایجاد شی تاپل حتی می‌توان از گذاردن پرانتز صرف نظر کرد و تنها اشیا (یا عبارت‌ها) را با کاما از یکدیگر جدا نمود:: - - >>> 5, - (5,) - -:: - - >>> 1, 2 , 'a', 'b' - (1, 2, 'a', 'b') - -:: - - >>> t = 'p', 'y' - >>> t - ('p', 'y') - -:: - - >>> 5 > 1, True == 0 , 7-2 - (True, False, 5) - - - -.. note:: - نوع تاپل به دلیل تغییر ناپذیر بودن، نسبت به نوع لیست در مصرف حافظه بهینه‌تر می‌باشد؛ بنابراین بهتر است در مواقعی که نیاز به تغییر خاصی در داده‌ها نیست از این نوع استفاده شود. همچنین در مواقعی که نباید داده‌ها تغییر کنند، استفاده از شی تاپل به جای لیست می‌تواند از آن‌ها در برابر تغییر محافظت کند. - - -به دلیل شباهت‌های بسیار شی تاپل به شی لیست از ارایه توضیحات تکراری اجتناب کرده و تنها به ذکر چند مثال در ارتباط با نوع تاپل می‌پردازیم:: - - >>> ('a', 'b', 'c') + (1 , 2, 3) - ('a', 'b', 'c', 1, 2, 3) - - >>> ('python', 0) * 3 - ('python', 0, 'python', 0, 'python', 0) - -:: - - >>> t = ('p', 'y', [1, 2, 3], 5) - - >>> 'p' in t - True - >>> 2 not in t - True - >>> [1, 2, 3] not in t - False - -:: - - >>> (1, 'python') == (1, 'python') - True - >>> (1, 'python') == (1, 'PYTHON') - False - -:: - - >>> t1 = (1, 2, 3) - >>> t2 = t1 - >>> t2 == t1 - True - >>> t2 is t1 - True - - >>> t1 = (1, 2, 3) - >>> t2 = (1, 2, 3) - >>> t2 == t1 - True - >>> t2 is t1 - False - -:: - - >>> t = ('p', 'y', [1, 2, 3], 5) - - >>> t[0] - 'p' - >>> t[-1] - 5 - >>> t[:2] - ('p', 'y') - >>> t[2] - [1, 2, 3] - >>> t[2][1] - 2 - - >>> t[0] = 'j' - Traceback (most recent call last): - File "", line 1, in - TypeError: 'tuple' object does not support item assignment - -:: - - >>> t = ('p', 'y', [1, 2, 3], 5) - - >>> len(t) - 4 - >>> len(t[2]) - 3 - -به دلیل ساختار ارجاعی بین اشیا در پایتون که توسط تصاویر بخش لیست نیز نمایش داده شد؛ اشیا تغییر پذیر درون شی تاپل، ویژگی‌های خود را داشته و همچنان تغییر پذیر خواهند بود:: - - >>> t = ('p', 'y', [1, 2, 3], 5) - - >>> t[2][1] = 8 - >>> t - ('p', 'y', [1, 8, 3], 5) - -همچنین به نمونه کدهای پایین در مورد Unpacking توجه نمایید:: - - >>> a, *b = (1.1, 2.2, 3.3, 4.4) - - >>> a - 1.1 - >>> b - [2.2, 3.3, 4.4] - -:: - - >>> a, *b, c = (1.1, 2.2, 3.3, 4.4) - - >>> a - 1.1 - >>> b - [2.2, 3.3] - >>> c - 4.4 - -:: - - >>> a, *b = [1.1, 2.2, (3.3, 4.4)] - - >>> a - 1.1 - >>> b - [2.2, (3.3, 4.4)] - -:: - - >>> a, *b, c = [1.1, 2.2, (3.3, 4.4)] - - >>> a - 1.1 - >>> b - [2.2] - >>> c - (3.3, 4.4) - -:: - - >>> a, *b, c = (1.1, 2.2, (3.3, 4.4)) - - >>> a - 1.1 - >>> b - [2.2] - >>> c - (3.3, 4.4) - -*حتما متوجه شده‌اید که عضوهای دنباله تنها با نوع لیست به نام نشانه‌گذاری شده انتساب داده می‌شود.* - - -در هنگام انتساب متغیر تاپل به موضوع کپی نشدن اشیا تغییر پذیر توجه داشته باشید و در صورت نیاز از ماژول ``copy`` استفاده نمایید:: - - >>> t1 = ('p', 'y', [1, 2, 3], 5) - - >>> t2 = t1 # No Copy - - >>> t1[2][1] = 8 - - >>> t1 - ('p', 'y', [1, 8, 3], 5) - >>> t2 - ('p', 'y', [1, 8, 3], 5) - -:: - - >>> t1 = ('p', 'y', [1, 2, 3], 5) - - >>> import copy - >>> t2 = copy.deepcopy(t1) # Deep Copy - - >>> t1[2][1] = 8 - - >>> t1 - ('p', 'y', [1, 8, 3], 5) - >>> t2 - ('p', 'y', [1, 2, 3], 5) - - - -همانند شی لیست؛ شی تاپل نیز به دو متد ``()index`` و ``()count`` دسترسی دارد - این موضوع با استفاده از تابع ``()dir`` قابل بررسی است:: - - >>> t = ('s', 'b', 'c', 'a', 's', 'b') - -:: - - >>> dir(t) - ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index'] - -:: - - >>> t.index('b') - 1 - - >>> t.index('b', 2) - 5 - - >>> t.index('z') - Traceback (most recent call last): - File "", line 1, in - ValueError: tuple.index(x): x not in tuple - -:: - - >>> t.count('a') - 3 - >>> t.count(5) - 0 - -استفاده از راهنما را که فراموش نکرده‌اید؟!:: - - >>> t = ('s', 'b', 'c', 'a', 's', 'b') - - >>> help(t.index) - - Help on built-in function index: - - index(...) method of builtins.tuple instance - T.index(value, [start, [stop]]) -> integer -- return first index of value. - Raises ValueError if the value is not present. - (END) - - -هر زمان که نیاز به اِعمال تغییر در شی تاپل باشد؛ می‌توان شی مورد نظر را به صورت موقت به یک شی لیست تبدیل کرد. در این حالت می‌توان از ویژگی و متدهای شی لیست بهره برد و تغییرات دلخواه را اعمال کرد و در نهایت با یک تبدیل نوع دیگر دوباره به شی تاپل بازگشت. برای این منظور می‌توان با استفاده از کلاس ``()list`` یک دنباله - در اینجا یک شی تاپل - را به شی لیست تبدیل کرد و در طرف دیگر توسط کلاس ``()tuple`` نیز یک دنباله - در اینجا یک شی لیست - را به شی تاپل تبدیل نمود:: - - >>> t = (1, 2, 3) - >>> type(t) - - - >>> L = list(t) - >>> type(L) - - >>> L - [1, 2, 3] - - >>> L.insert(0, 'python') - >>> L - ['python', 1, 2, 3] - - >>> t = tuple(L) - >>> t - ('python', 1, 2, 3) - - -البته در مواقعی که می‌خواهید عضوهای درون یک شی تاپل را مرتب (Sort) کنید، نیازی به تبدیل نوع لیست نمی‌باشد و می‌توانید از تابع ``()sorted`` استفاده نمایید؛ این تابع مطابق آنچه که پیش از این معرفی شد یک شی تاپل را می‌گیرد و یک شی لیست با همان عضوها اما مرتب شده را برمی‌گرداند:: - - >>> t = ('a', 'D', 'c', 'B', 'e', 'f', 'G', 'h') - - >>> sorted(t, key=str.lower, reverse=True) - ['h', 'G', 'f', 'e', 'D', 'c', 'B', 'a'] - - -کلاس ``()tuple`` بدون آرگومان یک شی تاپل خالی را ایجاد می‌کند:: - - >>> t = tuple() - >>> t - () - >>> 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/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 - جمعه ۲۵ فروردین ۱۴۰۲

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