|
2 | 2 |
|
3 | 3 | .. meta:: |
4 | 4 | :description: پایتون به پارسی - کتاب آنلاین و آزاد آموزش زبان برنامهنویسی پایتون - درس نهم: دستورهای کنترلی در پایتون |
5 | | - :keywords: معرفی پایتون, تاریخچه پایتون, کارایی پایتون, نسخه های پایتون, ویژگی های پایتون, آشنایی با پایتون, آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون |
| 5 | + :keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون، حلقه تکرار در پایتون، for، while و match/case در پایتون، دستورهای انتخاب در پایتون، دستور if/elif/else در پایتون، شی iterator در پایتون |
6 | 6 |
|
7 | 7 |
|
8 | 8 | .. _lesson-09: |
|
22 | 22 |
|
23 | 23 | در حالت عادی جریان اجرای یک برنامه روند ثابتی دارد به این شکل که کدها سطر به سطر، از بالا به پایین خوانده و اجرا میشوند؛ دستورهای کنترلی امکانی برای کنترل یا تغییر این جریان ثابت است. با استفاده از این دستورها میتوان برای اجرای یک بلاک شرط تعیین کرد که اگر در زمان اجرا این شرط برقرار نباشد از اجرای بلاک صرف نظر خواهد شد یا میتوان شرایطی را به وجود آورد که اجرای یک بلاک را از میان چندین بلاک مشخص انتخاب گردد و همچنین میتوان اجرای یک بلاک را چندین بار تکرار کرد. |
24 | 24 |
|
25 | | -این درس به بررسی دستورهای کنترلی پایتون در دو بخش «انتخاب» و «تکرار» اختصاص یافته است. |
| 25 | +این درس به بررسی دستورهای کنترلی پایتون در دو بخش «انتخاب» و «تکرار» اختصاص یافته است. در انتها نیز بنابر ضرورت به معرفی اشیای iterator در پایتون پرداخته شده است. |
26 | 26 |
|
27 | 27 |
|
28 | 28 |
|
|
281 | 281 | دستور match/case |
282 | 282 | ~~~~~~~~~~~~~~~~~~~~ |
283 | 283 |
|
284 | | -در صورتی که سابقه برنامهنویسی با زبانهای دیگری همچون C و Java را داشته باشید حتما با دستور switch نیز آشنا هستید؛ تا پیش **از نسخه 3.10 پایتون** این دستور در زبان پایتون پیادهسازی نشده بود و تنها میتوانستیم از ساختار ``if/elif/else`` استفاده نماییم. ولی اکنون پایتون از ساختار مشابهی به نام ``match/case`` پشتیبانی میکند که ساختاری برابر زیر دارد:: |
| 284 | +در صورتی که سابقه برنامهنویسی با زبانهای دیگری همچون C و Java را داشته باشید حتما با دستور switch نیز آشنا هستید؛ تا پیش **از نسخه 3.10 پایتون** این دستور در زبان پایتون پیادهسازی نشده بود و تنها میتوانستیم از ساختار ``if/elif/else`` استفاده نماییم. ولی اکنون پایتون از ساختار مشابهی به نام ``match/case`` پشتیبانی میکند که ساختاری برابر زیر دارد (برای مطالعه بیشتر: [`PEP 634 <https://peps.python.org/pep-0634/>`__] و [`PEP 635 <https://peps.python.org/pep-0635/>`__] و [`PEP 636 <https://peps.python.org/pep-0636/>`__]):: |
285 | 285 |
|
286 | 286 |
|
287 | 287 | match value: |
|
313 | 313 | Four |
314 | 314 | >>> |
315 | 315 |
|
316 | | -در مثال بالا مقدار حروفی مربوط به عدد اندیس یکم از شی list چاپ خواهد شد. |
| 316 | +در مثال بالا مقدار حروفی مربوط به عدد اندیس صفر از شی list چاپ خواهد شد. |
317 | 317 |
|
318 | 318 | مثالی دیگر، تشخیص زوج بودن یک عدد:: |
319 | 319 |
|
|
381 | 381 | به این نگارش یا سینتکس از دستور ``if`` در جامعه پایتون، تکنیک ``guard`` گفته میشود. در این ساختار متغیری که در پشت ``if`` قرار میگیرد، همان مقدار دریافتی است. این متغیر میتواند هر نامی داشته باشد ولی حتما میبایست با متغیر درون دستور ``if`` همنام باشد (در مثال بالا برای جلوگیری از ابهام، همنام با خود مقدار دریافتی در نظر گرفته شده است). در این شرایط چنانچه ارزیابی دستور ``if`` برابر مقدار ``True`` باشد، دستورهای ``case`` آن اجرا میگردد و در غیر اینصورت الگوی ``case`` بعدی مورد پردازش قرار خواهد گرفت. |
382 | 382 |
|
383 | 383 |
|
384 | | -.. _python-loop: |
| 384 | +.. _python-repetition: |
385 | 385 |
|
386 | 386 | تکرار |
387 | 387 | ------- |
|
507 | 507 | >>> |
508 | 508 |
|
509 | 509 |
|
| 510 | +.. _python-for: |
510 | 511 |
|
511 | 512 | دستور for |
512 | 513 | ~~~~~~~~~~ |
|
635 | 636 |
|
636 | 637 | .. rubric:: تابع ``(range(stop``: |
637 | 638 |
|
638 | | -این تابع [`اسناد پایتون 3x <http://docs.python.org/3/library/functions.html#func-range>`__] یک شی از نوع ``range`` را برمیگرداند؛ این شی یک دنباله تغییر ناپذیر است که معمولا از آن برای پیمایش در حلقه ``for`` استفاده میشود. با تبدیل شی ``range`` به نوع لیست خواهیم دید که این شی یک دنباله مرتب از اعداد صفر تا آرگومان stop (و نه خود آن) است؛ آرگومان stop میبایست یک عدد صحیح مثبت باشد:: |
| 639 | +این تابع [`اسناد پایتون <http://docs.python.org/3/library/functions.html#func-range>`__] یک شی از نوع ``range`` را برمیگرداند؛ این شی یک دنباله تغییر ناپذیر است که معمولا از آن برای پیمایش در حلقه ``for`` استفاده میشود. با تبدیل شی ``range`` به نوع لیست خواهیم دید که این شی یک دنباله مرتب از اعداد صفر تا آرگومان stop (و نه خود آن) است؛ آرگومان stop میبایست یک عدد صحیح مثبت باشد:: |
639 | 640 |
|
640 | | - >>> r = range(10) # Python 3.x |
| 641 | + >>> r = range(10) |
641 | 642 |
|
642 | 643 | >>> type(r) |
643 | 644 | <class 'range'> |
|
696 | 697 | >>> list(range(-2, -10, -2)) |
697 | 698 | [-2, -4, -6, -8] |
698 | 699 |
|
699 | | -در نسخههای 2x پایتون دو نسخه از این تابع وجود دارد: تابع ``range`` [`اسناد پایتون 2x <http://docs.python.org/2/library/functions.html#range>`__] و تابع ``xrange`` [`اسناد پایتون 2x <http://docs.python.org/2/library/functions.html#xrange>`__]. |
700 | | - |
701 | | -خروجی تابع ``range`` یک شی از نوع لیست است:: |
702 | | - |
703 | | - >>> r = range(10) # Python 2.x |
704 | | - |
705 | | - >>> type(r) |
706 | | - <type 'list'> |
707 | | - |
708 | | - >>> r |
709 | | - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
710 | | - |
711 | | - >>> import sys |
712 | | - >>> sys.getsizeof(r) |
713 | | - 152 |
714 | | - |
715 | | - |
716 | | - |
717 | | -ولی خروجی تابع ``xrange`` یک شی از نوع ``xrange`` میباشد:: |
718 | | - |
719 | | - >>> r = xrange(10) # Python 2.x |
720 | | - |
721 | | - >>> type(r) |
722 | | - <type 'xrange'> |
723 | | - |
724 | | - >>> r |
725 | | - xrange(10) |
726 | | - |
727 | | - >>> list(r) |
728 | | - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
729 | | - |
730 | | - >>> import sys |
731 | | - >>> sys.getsizeof(r) |
732 | | - 40 |
733 | | - |
734 | | - |
735 | | -خروجی تابع ``xrange`` سادهتر و بهینه تر از خروجی تابع ``range`` است بنابراین معمولا پیشنهاد میشود که در حلقه ``for`` از تابع ``xrange`` استفاده شود؛ به همین دلیل میباشد که تابع ``range`` در نسخههای 3x پایتون حذف شده است و تنها تابع ``xrange`` باقیمانده که با نام و نوع ``range`` پیادهسازی شده است. |
736 | | - |
737 | | -* چگونگی استفاده و تعداد آرگومانهای هر دو تابع همانند نسخه 3x است که پیش از این بررسی شد. |
738 | 700 |
|
739 | 701 | .. rubric:: چند مثال ساده دیگر: |
740 | 702 |
|
|
800 | 762 | >>> [x ** 2 for x in range(5)] |
801 | 763 | [0, 1, 4, 9, 16] |
802 | 764 |
|
| 765 | +این عمل، List Comprehensions خوانده میشود که توسط درس سیزدهم شرح داده خواهد شد. |
| 766 | + |
803 | 767 | و به عنوان مثالهایی دیگر به نمونه کدهای پایین توجه نمایید:: |
804 | 768 |
|
805 | 769 | >>> y = 7 |
|
844 | 808 | 4 |
845 | 809 | >>> |
846 | 810 |
|
847 | | -به نمونه کد بالا توجه نمایید؛ با هر بار تکرار حلقه یکم تمام دستورهای بدنه آن که شامل یک حلقه دیگر است اجرا میگردد. از متغیر ``i`` درون حلقه داخلی نیز استفاده شده است. در بار نخستِ اجرای حلقه بیرونی مقدار ``i`` برابر عدد ``1`` قرار داده میشود که در این صورت اجرای حلقه داخلی تنها یک بار تکرار میگردد (``1 == ((len(range(0, 1``) و یک مقدار ``1`` در خروجی نمایش داده میشود، بار دوم ``i`` برابر عدد ``2`` میشود و در نتیجه حلقه داخلی دو بار تکرار میگردد که بر اثر آن دو مقدار ``2`` در خروجی چاپ میگردد. این روند تا پایان تکرار حلقه بیرونی ادامه مییابد. |
| 811 | +به نمونه کد بالا توجه نمایید؛ با هر بار تکرار حلقه یکم تمام دستورهای بدنه آن که شامل یک حلقه دیگر است اجرا میگردد. از متغیر ``i`` درون حلقه داخلی نیز استفاده شده است. در بار نخستِ اجرای حلقه بیرونی مقدار ``i`` برابر عدد ``1`` قرار داده میشود که در این صورت اجرای حلقه داخلی تنها یک بار تکرار میگردد ``1 == ((len(range(0, 1`` و یک مقدار ``1`` در خروجی نمایش داده میشود، بار دوم ``i`` برابر عدد ``2`` میشود و در نتیجه حلقه داخلی دو بار تکرار میگردد که بر اثر آن دو مقدار ``2`` در خروجی چاپ میگردد. این روند تا پایان تکرار حلقه بیرونی ادامه مییابد. |
848 | 812 |
|
849 | | -*تابع (یا دستور) print به صورت پیشفرض پس از اجرا و چاپ مقدار به سطر بعدی میرود. [در درس بعد چگونگی تغییر این رفتار بررسی خواهد شد]* |
| 813 | +*تابع print به صورت پیشفرض پس از اجرا و چاپ مقدار به سطر بعدی میرود. [در درس بعد چگونگی تغییر این رفتار بررسی خواهد شد]* |
850 | 814 |
|
851 | 815 |
|
852 | 816 | اگر از پیش با زبانهایی نظیر C یا Java آشنایی دارید؛ برای درک بهتر ساختار حلقه ``for`` پایتون نمونه کد پایین که به زبان Java است را در نظر بگیرید: |
|
910 | 874 |
|
911 | 875 | >>> s = 'python' |
912 | 876 |
|
913 | | - >>> for i, v in enumerate(s): |
914 | | - ... print('%s) %s' % (i, v * 7)) |
| 877 | + >>> for index, value in enumerate(s): |
| 878 | + ... print('%s) %s' % (index, value * 7)) |
915 | 879 | ... |
916 | 880 | 0) ppppppp |
917 | 881 | 1) yyyyyyy |
|
940 | 904 | [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')] |
941 | 905 |
|
942 | 906 |
|
943 | | -.. rubric:: شی تکرارکننده |
| 907 | +.. _python-iterator: |
| 908 | + |
| 909 | +شی تکرارکننده (iterator) |
| 910 | +---------------------------------------------- |
944 | 911 |
|
945 | 912 | در این بخش قصد داریم با مفهوم iterator (تکرارکننده) در پایتون آشنا شویم. برای این منظور بهتر است ابتدا مفهوم iterable (تکرارپذیر) را بدانیم. |
946 | 913 |
|
947 | | -تمام انواع دنباله یک iterable هستند؛ در واقع به اشیایی با این قابلیت که بتوان در هر لحظه یک عضو درون آن را دستیابی نمود iterable گفته میشود. اکثر انواع آماده شی که در پایتون میشناسیم یک iterable است؛ انواع شی رشته، لیست، توپِل، دیکشنری، range ،zip (یا xrange) یا یک شی فایل (file) و هر شی از کلاسی که خودتان به همراه متدهای ویژه ``()__iter__`` یا ``()__getitem__`` تعریف نمایید یک iterable هستند. |
| 914 | +تمام انواع دنباله یک iterable هستند؛ در واقع به اشیایی با این قابلیت که بتوان در هر لحظه یک عضو درون آن را دستیابی نمود iterable گفته میشود. اکثر انواع آماده شی که در پایتون میشناسیم یک iterable است؛ انواع شی رشته، لیست، توپِل، دیکشنری، range ،zip یا یک شی فایل (file) و هر شی از کلاسی که خودتان به همراه متد ویژه ``()__iter__`` تعریف نمایید یک iterable هستند [`ویکیپایتون <https://wiki.python.org/moin/Iterator>`__]. |
| 915 | + |
| 916 | +در آینده پس از مطالعه دروس مربوط به شی گرایی (هفدهم تا بیست و دوم) قادر به ساخت کلاس و استفاده از متدهای ویژه در پایتون خواهید بود. در آن زمان می توانید خود با پیادهسازی متد ویژه ``()__next__`` یک شی iterator ایجاد نمایید. اما در این مرحله ما فرآیند ایجاد را با یک ماژول از کتابخانه استاندارد پایتون پیش خواهیم برد. |
| 917 | + |
| 918 | +میتوان یک شی iterator را تنها با استفاده از تابع آماده ``()iter`` [`اسناد پایتون <http://docs.python.org/3/library/functions.html#iter>`__] ایجاد کرد. این تابع یک شی iterable را به عنوان آرگومان دریافت میکند و یک شی iterator از آن بر میگرداند:: |
948 | 919 |
|
949 | | -شی iterator با استفاده از تابع آماده ``()iter`` [`اسناد پایتون <http://docs.python.org/3/library/functions.html#iter>`__] ایجاد میشود؛ این تابع یک شی iterable را به عنوان آرگومان دریافت میکند و آن را در قالب یک شی iterator بر میگرداند:: |
950 | 920 |
|
951 | 921 | >>> L = [1, 2, 3, 4, 5] |
952 | 922 | >>> type(L) |
|
990 | 960 | >>> type(itr) |
991 | 961 | <class 'dict_keyiterator'> |
992 | 962 |
|
993 | | -یک شی iterator این قابلیت را دارد که میتوان عضوهای درون آن را یکی یکی با استفاده از متد ``()__next__`` (یا ``()next`` در پایتون 2x) پیمایش کرد؛ این متد در بار نخستِ فراخوانی عضو یکم شی و در دفعات بعدی فراخوانی به ترتیب عضوهای بعدی را برمیگرداند:: |
| 963 | +یک شی iterator این قابلیت را دارد که میتوان عضوهای درون آن را یکی یکی با استفاده از متد ``()__next__`` پیمایش کرد؛ این متد در بار نخستِ فراخوانی عضو یکم شی و در دفعات بعدی فراخوانی به ترتیب عضوهای بعدی را برمیگرداند:: |
994 | 964 |
|
995 | 965 | >>> L = [1, 2, 3, 4, 5] |
996 | 966 | >>> itr = iter(L) |
997 | 967 |
|
998 | 968 | :: |
999 | 969 |
|
1000 | | - >>> # Python 3.x |
1001 | | - |
1002 | 970 | >>> itr.__next__() |
1003 | 971 | 1 |
1004 | 972 | >>> itr.__next__() |
1005 | 973 | 2 |
1006 | 974 | >>> itr.__next__() |
1007 | 975 | 3 |
1008 | 976 |
|
1009 | | -:: |
1010 | | - |
1011 | | - >>> # Python 2.x |
1012 | | - |
1013 | | - >>> itr.next() |
1014 | | - 1 |
1015 | | - >>> itr.next() |
1016 | | - 2 |
1017 | | - >>> itr.next() |
1018 | | - 3 |
1019 | | - |
1020 | 977 | با فراخوانی پی در پی این متد و رسیدن به انتهای پیمایش؛ زمانی که دیگر عضوی برای برگرداندن وجود ندارد یک خطا - البته درست این است که بگوییم یک استثنا (Exception) - با نام ``StopIteration`` گزارش میگردد:: |
1021 | 978 |
|
1022 | 979 | >>> itr.__next__() |
|
1030 | 987 |
|
1031 | 988 | این دقیقا همان کاری است که در دستور ``for`` به انجام میرسد. زمانی که از یک دنباله برای پیمایش در این دستور استفاده میکنید؛ ``for`` در پشت صحنه آن را به یک iterator تبدیل و سپس پیمایش یک به یک عضوها را آغاز میکند. در هر لحظه که ``StopIteration`` رخ دهد، متوجه پایان دنباله شده و تکرار حلقه را پایان میبخشد. |
1032 | 989 |
|
1033 | | -در آینده توسط درس استثناها در پایتون خواهید دید که میتوان با ایجاد iterator و استفاده از دستور ``try/except`` [که در همان درس خواهید آموخت] یک حلقه ``while`` را به مانند حلقه ``for`` پیادهسازی کرد. |
1034 | | - |
1035 | 990 |
|
1036 | 991 | با استفاده از ماژول ``itertools`` میتوانید iterator های بینهایت (Infinite) یا بدون توقف ایجاد نمایید. برای نمونه تابع ``cycle`` درون این ماژول، شی iterator ای میسازد که در انتهای پیمایش متوقف نمیشود و از نو به ابتدای شی برگشته و عضو یکم را برمیگرداند:: |
1037 | 992 |
|
|
1069 | 1024 |
|
1070 | 1025 | :emoji-size:`😊` امیدوارم مفید بوده باشه |
1071 | 1026 |
|
1072 | | -`لطفا دیدگاه و سوالهای مرتبط با این درس خود را در کدرز مطرح نمایید. <http://coderz.ir/python-tutorial-control-statements/>`_ |
1073 | | - |
1074 | 1027 |
|
0 commit comments