از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
باز کردن بسته بندی در پایتون: فراتر از تعیین موازی
سرفصلهای مطلب
معرفی
باز کردن بسته بندی در پایتون به عملیاتی اشاره دارد که شامل تخصیص مقادیر تکرارشونده به یک تاپل (یا list
) از متغیرها در یک دستور انتساب. به عنوان مکمل، اصطلاح بسته بندی می تواند زمانی استفاده شود که چندین مقدار را در یک متغیر با استفاده از عملگر unpacking تکرارپذیر جمع آوری کنیم، *
.
از لحاظ تاریخی، توسعه دهندگان پایتون به طور کلی این نوع عملیات را به عنوان باز کردن بسته بندی تاپل. با این حال، از آنجایی که این ویژگی پایتون کاملاً مفید و محبوب است، به انواع تکرارپذیرها تعمیم داده شده است. امروزه یک اصطلاح مدرن و دقیق تر خواهد بود باز کردن مجدد بسته بندی.
در این آموزش، ما یاد میگیریم که باز کردن بستهبندی تکرارپذیر چیست و چگونه میتوانیم از این ویژگی پایتون استفاده کنیم تا کد خود را خوانا، قابل نگهداری و پایتونیکتر کنیم.
علاوه بر این، ما همچنین چند مثال عملی از روش استفاده از ویژگی باز کردن بستهبندی تکرارپذیر در زمینه عملیات تکالیف را پوشش خواهیم داد. for
حلقه ها، تعاریف تابع و فراخوانی تابع.
بسته بندی و باز کردن بسته بندی در پایتون
پایتون اجازه می دهد تا a tuple
(یا list
) از متغیرهایی که ظاهر می شوند روی سمت چپ عملیات انتساب هر متغیر در tuple
می تواند یک مقدار (یا بیشتر، در صورت استفاده از.) دریافت کند *
عملگر) از یک تکرار شونده روی سمت راست تکلیف
به دلایل تاریخی، توسعه دهندگان پایتون قبلاً این را می نامیدند باز کردن بسته بندی تاپل. با این حال، از آنجایی که این ویژگی به همه انواع تکرارپذیر تعمیم داده شده است، اصطلاح دقیق تری خواهد بود باز کردن مجدد بسته بندی و این چیزی است که در این آموزش آن را می نامیم.
عملیات باز کردن بسته بندی در بین توسعه دهندگان پایتون بسیار محبوب بوده است زیرا می توانند کد ما را خواناتر و زیباتر کنند. بیایید نگاهی دقیقتر به باز کردن بستهبندی در پایتون بیندازیم و ببینیم چگونه این ویژگی میتواند کد ما را بهبود بخشد.
باز کردن تاپل ها
در پایتون می توانیم a قرار دهیم tuple
از متغیرها روی سمت چپ یک اپراتور انتساب (=
) و الف tuple
از ارزش ها روی سمت راست. ارزش ها روی سمت راست به طور خودکار به متغیرها اختصاص می یابد روی چپ با توجه به موقعیت خود در tuple
. این معمولا به عنوان شناخته شده است باز کردن بسته بندی تاپل در پایتون مثال زیر را بررسی کنید:
>>> (a, b, c) = (1, 2, 3)
>>> a
1
>>> b
2
>>> c
3
وقتی تاپل ها می گذاریم روی در هر دو طرف یک اپراتور تخصیص، عملیات باز کردن بسته بندی تاپل انجام می شود. ارزش ها روی سمت راست به متغیرها اختصاص داده می شود روی چپ با توجه به موقعیت نسبی خود در هر یک tuple
. همانطور که در مثال بالا می بینید، a
خواهد بود 1
، b
خواهد بود 2
، و c
خواهد بود 3
.
برای ایجاد یک tuple
شی، ما نیازی به استفاده از یک جفت پرانتز نداریم ()
به عنوان جداکننده این برای باز کردن بسته بندی تاپل نیز کار می کند، بنابراین دستورات زیر معادل هستند:
>>> (a, b, c) = 1, 2, 3
>>> a, b, c = (1, 2, 3)
>>> a, b, c = 1, 2, 3
از آنجایی که همه این تغییرات، نحو پایتون معتبری هستند، بسته به اینکه میتوانیم از هر کدام از آنها استفاده کنیم روی موقعیت. مسلماً آخرین نحو معمولاً در هنگام باز کردن بسته بندی در پایتون استفاده می شود.
هنگامی که ما در حال باز کردن مقادیر به متغیرها با استفاده از بسته بندی تاپل، تعداد متغیرها هستیم روی سمت چپ tuple
باید دقیقاً با تعداد مقادیر مطابقت داشته باشد روی سمت راست tuple
. در غیر این صورت، ما یک ValueError
.
برای مثال در کد زیر از دو متغیر استفاده می کنیم روی سمت چپ و سه مقدار روی حق این یک را افزایش می دهد ValueError
به ما می گوید که مقادیر زیادی برای باز کردن وجود دارد:
>>> a, b = 1, 2, 3
Traceback (most recent call last):
...
ValueError: too many values to unpack (expected 2)
توجه داشته باشید: تنها استثنا در این مورد زمانی است که ما از آن استفاده می کنیم *
عملگر برای بسته بندی چندین مقدار در یک متغیر همانطور که بعدا خواهیم دید روی.
از طرف دیگر، اگر از متغیرهای بیشتری نسبت به مقادیر استفاده کنیم، a را دریافت خواهیم کرد ValueError
اما این بار پیام می گوید که مقادیر کافی برای باز کردن بسته بندی وجود ندارد:
>>> a, b, c = 1, 2
Traceback (most recent call last):
...
ValueError: not enough values to unpack (expected 3, got 2)
اگر از تعداد متفاوتی از متغیرها و مقادیر در عملیات باز کردن بسته بندی تاپل استفاده کنیم، یک عدد دریافت می کنیم. ValueError
. این به این دلیل است که پایتون باید بدون ابهام بداند که چه مقداری در کدام متغیر قرار می گیرد، بنابراین می تواند تخصیص را مطابق با آن انجام دهد.
باز کردن Iterables
ویژگی باز کردن بسته بندی تاپل در میان توسعه دهندگان پایتون به قدری محبوب شد که این نحو برای کار با هر شیء تکرارپذیر گسترش یافت. تنها شرط این است که تکرار شونده دقیقاً یک آیتم در هر متغیر در دریافت کننده ارائه دهد tuple
(یا list
).
نمونههای زیر را از روش عملکرد باز کردن بستهبندی تکرارپذیر در پایتون بررسی کنید:
>>>
>>> a, b, c = '123'
>>> a
'1'
>>> b
'2'
>>> c
'3'
>>>
>>> a, b, c = (1, 2, 3)
>>> a
1
>>> b
2
>>> c
3
>>>
>>> gen = (i ** 2 for i in range(3))
>>> a, b, c = gen
>>> a
0
>>> b
1
>>> c
4
>>>
>>> my_dict = {'one': 1, 'two':2, 'three': 3}
>>> a, b, c = my_dict
>>> a
'one'
>>> b
'two'
>>> c
'three'
>>> a, b, c = my_dict.values()
>>> a
1
>>> b
2
>>> c
3
>>> a, b, c = my_dict.items()
>>> a
('one', 1)
>>> b
('two', 2)
>>> c
('three', 3)
وقتی نوبت به باز کردن بسته بندی در پایتون می رسد، می توانیم از هر تکرار شونده استفاده کنیم روی سمت راست اپراتور تخصیص سمت چپ را می توان با یک پر کرد tuple
یا با الف list
از متغیرها مثال زیر را بررسی کنید که در آن از a استفاده می کنیم tuple
روی سمت راست بیانیه تکلیف:
>>> (a, b, c) = 1, 2, 3
>>> a
1
>>> b
2
>>> c
3
اگر از آن استفاده کنیم به همین صورت عمل می کند range()
اشاره گر:
>>> x, y, z = range(3)
>>> x
0
>>> y
1
>>> z
2
اگرچه این یک نحو معتبر پایتون است، اما معمولاً در کد واقعی استفاده نمی شود و شاید برای توسعه دهندگان مبتدی پایتون کمی گیج کننده باشد.
در نهایت، ما نیز می توانیم استفاده کنیم set
اشیاء در عملیات باز کردن بسته بندی با این حال، از آنجایی که مجموعهها مجموعهای نامرتب هستند، ترتیب تکالیف میتواند به نوعی نامنسجم باشد و میتواند منجر به اشکالات ظریف شود. مثال زیر را بررسی کنید:
>>> a, b, c = {'a', 'b', 'c'}
>>> a
'c'
>>> b
'b'
>>> c
'a'
اگر از مجموعه ها در عملیات باز کردن بسته بندی استفاده کنیم، ترتیب نهایی تکالیف می تواند کاملاً با آنچه می خواهیم و انتظار داریم متفاوت باشد. بنابراین، بهتر است از استفاده از مجموعه ها در عملیات باز کردن بسته بندی خودداری کنید، مگر اینکه ترتیب انتساب برای کد ما مهم نباشد.
بسته بندی با اپراتور *
این *
اپراتور شناخته شده است، در این زمینه، به عنوان اپراتور باز کردن بسته بندی چندگانه (یا قابل تکرار).. این قابلیت باز کردن بسته بندی را گسترش می دهد تا به ما اجازه دهد چندین مقدار را در یک متغیر جمع آوری یا بسته بندی کنیم. در مثال زیر، a را بسته بندی می کنیم tuple
از مقادیر به یک متغیر واحد با استفاده از *
اپراتور:
>>> *a, = 1, 2
>>> a
(1, 2)
برای اینکه این کد کار کند، سمت چپ تکلیف باید a باشد tuple
(یا الف list
). به همین دلیل از کاما انتهایی استفاده می کنیم. این tuple
می تواند به تعداد متغیرهایی که نیاز داریم باشد. با این حال، فقط می تواند شامل یک مورد باشد بیان ستاره دار.
می توانیم با استفاده از عملگر unpacking یک عبارت خیره شده تشکیل دهیم، *
، همراه با یک شناسه معتبر پایتون، درست مانند *a
در کد بالا بقیه متغیرها در سمت چپ tuple
نامیده می شوند اجباری متغیرها چون باید با مقادیر مشخص پر شوند، در غیر این صورت، با خطا مواجه می شویم. در اینجا روش کار در عمل آمده است.
بسته بندی مقادیر انتهایی در b
:
>>> a, *b = 1, 2, 3
>>> a
1
>>> b
(2, 3)
بسته بندی مقادیر شروع در a
:
>>> *a, b = 1, 2, 3
>>> a
(1, 2)
>>> b
3
بسته بندی یک مقدار در a
زیرا b
و c
اجباری هستند:
>>> *a, b, c = 1, 2, 3
>>> a
(1)
>>> b
2
>>> c
3
بسته بندی بدون ارزش در a
(a
پیش فرض به ()
) زیرا b
، c
، و d
اجباری هستند:
>>> *a, b, c, d = 1, 2, 3
>>> a
()
>>> b
1
>>> c
2
>>> d
3
عدم ارائه مقدار برای یک متغیر اجباری (e
، بنابراین یک خطا رخ می دهد:
>>> *a, b, c, d, e = 1, 2, 3
...
ValueError: not enough values to unpack (expected at least 4, got 3)
بسته بندی مقادیر در یک متغیر با *
زمانی که ما نیاز به جمع آوری عناصر یک ژنراتور در یک متغیر واحد بدون استفاده از آن داریم، عملگر می تواند مفید باشد list()
تابع. در مثال های زیر از *
عملگر برای بسته بندی عناصر a بیان ژنراتور و الف دامنه اعتراض به یک متغیر منفرد:
>>> gen = (2 ** x for x in range(10))
>>> gen
<generator object <genexpr> at 0x7f44613ebcf0>
>>> *g, = gen
>>> g
(1, 2, 4, 8, 16, 32, 64, 128, 256, 512)
>>> ran = range(10)
>>> *r, = ran
>>> r
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
در این مثال ها، *
اپراتور عناصر را در آن بسته بندی می کند gen
، و ran
به g
و r
به ترتیب. با نحو او، ما از نیاز به فراخوانی اجتناب می کنیم list()
برای ایجاد یک list
از ارزش ها از a range
یک شیء، یک عبارت مولد یا یک تابع مولد.
توجه داشته باشید که ما نمی توانیم از عملگر باز کردن بسته بندی استفاده کنیم، *
، برای بسته بندی چندین مقدار در یک متغیر بدون افزودن کاما انتهایی به متغیر روی سمت چپ تکلیف بنابراین، کد زیر کار نخواهد کرد:
>>> *r = range(10)
File "<input>", line 1
SyntaxError: starred assignment target must be in a list or tuple
اگر سعی کنیم از *
عملگر برای بسته بندی چندین مقدار در یک متغیر واحد، سپس ما باید از singleton استفاده کنیم tuple
نحو. به عنوان مثال، برای اینکه مثال بالا عمل کند، فقط باید بعد از متغیر یک کاما اضافه کنیم r
، مانند در *r, = range(10)
.
استفاده از بسته بندی و باز کردن بسته بندی در عمل
عملیات بسته بندی و باز کردن بسته بندی می تواند در عمل بسیار مفید باشد. آنها می توانند کد شما را واضح، خوانا و پایتونیک کنند. بیایید نگاهی به چند مورد رایج در بسته بندی و باز کردن بسته بندی در پایتون بیندازیم.
تخصیص به صورت موازی
یکی از رایج ترین موارد استفاده از باز کردن بسته بندی در پایتون چیزی است که می توانیم آن را بنامیم تکلیف موازی. تخصیص موازی به شما امکان می دهد مقادیر یک تکرار شونده را به a اختصاص دهید tuple
(یا list
) از متغیرها در یک عبارت واحد و زیبا.
به عنوان مثال، فرض کنید ما یک پایگاه داده در مورد کارکنان شرکت خود داریم و باید هر مورد در لیست را به یک متغیر توصیفی اختصاص دهیم. اگر روش بازکردن بستهبندی تکرارپذیر در پایتون را نادیده بگیریم، میتوانیم کدهایی مانند این را برای خودمان بنویسیم:
>>> employee = ("John Doe", "40", "Software Engineer")
>>> name = employee(0)
>>> age = employee(1)
>>> job = employee(2)
>>> name
'John Doe'
>>> age
'40'
>>> job
'Software Engineer'
حتی اگر این کد کار می کند، مدیریت ایندکس می تواند دست و پا چلفتی، تایپ کردن سخت و گیج کننده باشد. یک راه حل تمیزتر، خواناتر و پایتونیک را می توان به صورت زیر کدگذاری کرد:
>>> name, age, job = ("John Doe", "40", "Software Engineer")
>>> name
'John Doe'
>>> age
40
>>> job
'Software Engineer'
با استفاده از Unpacking در پایتون، میتوانیم مشکل مثال قبلی را با یک عبارت ساده، ساده و زیبا حل کنیم. این تغییر کوچک، خواندن و درک کد ما را برای توسعه دهندگان تازه وارد آسان تر می کند.
مبادله مقادیر بین متغیرها
یکی دیگر از کاربردهای ظریف باز کردن بسته بندی در پایتون، مبادله مقادیر بین متغیرها بدون استفاده از متغیر موقت یا کمکی است. به عنوان مثال، فرض کنید نیاز داریم swap مقادیر دو متغیر a
و b
. برای انجام این کار، میتوانیم به راهحل سنتی پایبند باشیم و از یک متغیر موقت برای ذخیره مقدار مورد مبادله به صورت زیر استفاده کنیم:
>>> a = 100
>>> b = 200
>>> temp = a
>>> a = b
>>> b = temp
>>> a
200
>>> b
100
این روش سه مرحله و یک متغیر موقت جدید دارد. اگر از unpacking در پایتون استفاده کنیم، میتوانیم به همان نتیجه در یک مرحله واحد و مختصر دست پیدا کنیم:
>>> a = 100
>>> b = 200
>>> a, b = b, a
>>> a
200
>>> b
100
در بیانیه a, b = b, a
، ما در حال واگذاری مجدد هستیم a
به b
و b
به a
در یک خط کد این بسیار خواناتر و ساده تر است. همچنین توجه داشته باشید که با این تکنیک، نیازی به متغیر موقت جدید نیست.
جمع آوری مقادیر چندگانه با *
هنگامی که ما با برخی از الگوریتمها کار میکنیم، ممکن است شرایطی پیش بیاید که لازم باشد مقادیر یک تکرارپذیر یا یک دنباله را برای پردازش بیشتر به قطعاتی از مقادیر تقسیم کنیم. مثال زیر روش استفاده از a را نشان می دهد list
و عملیات برش برای انجام این کار:
>>> seq = (1, 2, 3, 4)
>>> first, body, last = seq(0), seq(1:3), seq(-1)
>>> first, body, last
(1, (2, 3), 4)
>>> first
1
>>> body
(2, 3)
>>> last
4
اگرچه این کد همانطور که ما انتظار داریم کار می کند، برخورد با شاخص ها و برش ها می تواند برای مبتدیان کمی آزاردهنده، دشوار باشد و گیج کننده باشد. همچنین دارای اشکالی است که کد را سفت و سخت می کند و نگهداری آن را دشوار می کند. در این وضعیت، اپراتور باز کردن بستهبندی تکرارپذیر، *
و توانایی آن در بسته بندی چندین مقدار در یک متغیر می تواند ابزار عالی باشد. این بازسازی کد بالا را بررسی کنید:
>>> seq = (1, 2, 3, 4)
>>> first, *body, last = seq
>>> first, body, last
(1, (2, 3), 4)
>>> first
1
>>> body
(2, 3)
>>> last
4
خط first, *body, last = seq
اینجا جادو می کند اپراتور باز کردن بسته بندی تکرارپذیر، *
، عناصر را در وسط جمع آوری می کند seq
که در body
. این باعث می شود کد ما خوانا، قابل نگهداری و انعطاف پذیرتر باشد. ممکن است فکر کنید، چرا انعطاف پذیرتر؟ خوب، فرض کنید که seq
طول آن در جاده تغییر می کند و شما هنوز باید عناصر میانی را در آن جمع کنید body
. در این مورد، از آنجایی که ما از Unpacking در پایتون استفاده می کنیم، برای کارکرد کد ما نیازی به تغییر نیست. این مثال را بررسی کنید:
>>> seq = (1, 2, 3, 4, 5, 6)
>>> first, *body, last = seq
>>> first, body, last
(1, (2, 3, 4, 5), 6)
اگر ما از برش دنباله به جای بازکردن مجدد در پایتون استفاده میکردیم، باید شاخصها و برشهای خود را بهروزرسانی کنیم تا مقادیر جدید را به درستی دریافت کنیم.
استفاده از *
عملگر برای بستهبندی چندین مقدار در یک متغیر میتواند در پیکربندیهای مختلفی اعمال شود، مشروط بر اینکه پایتون بتواند بدون ابهام تعیین کند که چه عنصر (یا عناصر) را به هر متغیر اختصاص دهد. به نمونه های زیر دقت کنید:
>>> *head, a, b = range(5)
>>> head, a, b
((0, 1, 2), 3, 4)
>>> a, *body, b = range(5)
>>> a, body, b
(0, (1, 2, 3), 4)
>>> a, b, *tail = range(5)
>>> a, b, tail
(0, 1, (2, 3, 4))
ما می توانیم حرکت دهیم *
اپراتور در tuple
(یا list
) از متغیرها برای جمع آوری مقادیر با توجه به نیازهای ما. تنها شرط این است که پایتون بتواند تعیین کند که هر مقدار را به چه متغیری اختصاص دهد.
توجه به این نکته مهم است که نمیتوانیم بیش از یک عبارت خیره شده در تکلیف استفاده کنیم، اگر این کار را انجام دهیم، یک عدد دریافت میکنیم. SyntaxError
به شرح زیر است:
>>> *a, *b = range(5)
File "<input>", line 1
SyntaxError: two starred expressions in assignment
اگر از دو یا بیشتر استفاده کنیم *
در یک عبارت انتساب، سپس یک را دریافت خواهیم کرد SyntaxError
به ما گفت که عبارت دو ستاره پیدا شد. به این دلیل است که پایتون نمی تواند به طور واضح تعیین کند که ما می خواهیم چه مقدار (یا مقادیر) را به هر متغیر اختصاص دهیم.
حذف مقادیر غیر ضروری با *
یکی دیگر از موارد استفاده رایج از *
عملگر این است که از آن با یک نام متغییر ساختگی برای حذف برخی از مقادیر بی فایده یا غیر ضروری استفاده کند. مثال زیر را بررسی کنید:
>>> a, b, *_ = 1, 2, 0, 0, 0, 0
>>> a
1
>>> b
2
>>> _
(0, 0, 0, 0)
برای مثال روشنتر از این مورد، فرض کنید ما در حال توسعه اسکریپتی هستیم که نیاز به تعیین نسخه پایتون مورد استفاده ما دارد. برای این کار می توانیم از sys.version_info
صفت. این ویژگی یک تاپل حاوی پنج مؤلفه شماره نسخه را برمیگرداند: major
، minor
، micro
، releaselevel
، و serial
. اما ما فقط نیاز داریم major
، minor
، و micro
برای اینکه اسکریپت ما کار کند، بنابراین ما می توانیم بقیه را رها کنیم. در اینجا یک مثال است:
>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=8, micro=1, releaselevel='final', serial=0)
>>> mayor, minor, micro, *_ = sys.version_info
>>> mayor, minor, micro
(3, 8, 1)
اکنون سه متغیر جدید با اطلاعات مورد نیاز داریم. بقیه اطلاعات در متغیر ساختگی ذخیره می شود _
، که می تواند توسط برنامه ما نادیده گرفته شود. این می تواند برای توسعه دهندگان تازه وارد روشن کند که ما نمی خواهیم (یا نیازی به) از اطلاعات ذخیره شده در _
زیرا این شخصیت معنای ظاهری ندارد.
توجه داشته باشید: به طور پیش فرض، کاراکتر زیر خط _
توسط مفسر پایتون برای ذخیره مقدار حاصل از عباراتی که در یک جلسه تعاملی اجرا می کنیم استفاده می شود. بنابراین، در این زمینه، استفاده از این کاراکتر برای شناسایی متغیرهای ساختگی می تواند مبهم باشد.
برگرداندن تاپل ها در توابع
توابع پایتون می توانند چندین مقدار جدا شده با کاما را برگردانند. از آنجایی که می توانیم تعریف کنیم tuple
اشیاء بدون استفاده از پرانتز، این نوع عملیات را می توان به عنوان برگرداندن a تفسیر کرد tuple
از ارزش ها اگر تابعی را کدنویسی کنیم که چندین مقدار را برمی گرداند، می توانیم عملیات بسته بندی و بازکردن مجدد را با مقادیر برگشتی انجام دهیم.
مثال زیر را بررسی کنید که در آن تابعی را برای محاسبه مربع و مکعب یک عدد معین تعریف می کنیم:
>>> def powers(number):
... return number, number ** 2, number ** 3
...
>>>
>>> result = powers(2)
>>> result
(2, 4, 8)
>>>
>>> number, square, cube = powers(2)
>>> number
2
>>> square
4
>>> cube
8
>>> *_, cube = powers(2)
>>> cube
8
اگر تابعی را تعریف کنیم که مقادیر جدا شده با کاما را برمی گرداند، می توانیم هر عملیات بسته بندی یا باز کردن را انجام دهیم. روی این ارزش ها
ادغام تکرارپذیرها با اپراتور *
یکی دیگر از موارد استفاده جالب برای اپراتور باز کردن بسته بندی، *
، توانایی ادغام چندین تکرار در یک دنباله نهایی است. این قابلیت برای لیست ها، تاپل ها و مجموعه ها کار می کند. به نمونه های زیر دقت کنید:
>>> my_tuple = (1, 2, 3)
>>> (0, *my_tuple, 4)
(0, 1, 2, 3, 4)
>>> my_list = (1, 2, 3)
>>> (0, *my_list, 4)
(0, 1, 2, 3, 4)
>>> my_set = {1, 2, 3}
>>> {0, *my_set, 4}
{0, 1, 2, 3, 4}
>>> (*my_set, *my_list, *my_tuple, *range(1, 4))
(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)
>>> my_str = "123"
>>> (*my_set, *my_list, *my_tuple, *range(1, 4), *my_str)
(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, '1', '2', '3')
میتوانیم از عملگر باز کردن بستهبندی تکرارپذیر استفاده کنیم، *
، هنگام تعریف دنباله هایی برای باز کردن عناصر یک دنباله فرعی (یا قابل تکرار) در دنباله نهایی. این به ما امکان می دهد تا دنباله ها را ایجاد کنیم روی پرواز از سایر دنباله های موجود بدون فراخوانی متدهایی مانند append()
، insert()
، و غیره روی.
دو مثال آخر نشان می دهد که این روش خواناتر و کارآمدتر برای به هم پیوستن تکرارپذیرها است. به جای نوشتن list(my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str)
ما فقط می نویسیم (*my_set, *my_list, *my_tuple, *range(1, 4), *my_str)
.
باز کردن دیکشنری ها با اپراتور **
در زمینه باز کردن بسته بندی در پایتون، **
اپراتور نامیده می شود اپراتور بازگشایی دیکشنری. استفاده از این اپراتور توسط PEP 448. اکنون میتوانیم آن را در فراخوانی تابع، در درک و عبارات مولد و در استفاده کنیم نمایش می دهد.
یک مورد اساسی برای عملگر بازگشایی فرهنگ لغت، ادغام چندین فرهنگ لغت در یک فرهنگ لغت نهایی با یک عبارت واحد است. بیایید ببینیم این چگونه کار می کند:
>>> numbers = {"one": 1, "two": 2, "three": 3}
>>> letters = {"a": "A", "b": "B", "c": "C"}
>>> combination = {**numbers, **letters}
>>> combination
{'one': 1, 'two': 2, 'three': 3, 'a': 'A', 'b': 'B', 'c': 'C'}
اگر از عملگر بازگشایی دیکشنری در نمایشگر دیکشنری استفاده کنیم، میتوانیم دیکشنریها را باز کرده و آنها را برای ایجاد یک فرهنگ لغت نهایی که شامل جفتهای کلید-مقدار دیکشنریهای اصلی است، ترکیب کنیم، درست مانند آنچه در کد بالا انجام دادیم.
نکته مهمی که باید به آن توجه داشت این است که اگر دیکشنریهایی که میخواهیم ادغام کنیم دارای کلیدهای تکراری یا مشترک باشند، آنگاه مقادیر فرهنگ لغت سمت راست بر مقادیر فرهنگ لغت با سمت چپ لغو میشوند. در اینجا یک مثال است:
>>> letters = {"a": "A", "b": "B", "c": "C"}
>>> vowels = {"a": "a", "e": "e", "i": "i", "o": "o", "u": "u"}
>>> {**letters, **vowels}
{'a': 'a', 'b': 'B', 'c': 'C', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'}
از آنجا که a
کلید در هر دو فرهنگ لغت وجود دارد، ارزش غالب از آن ناشی می شود vowels
، که راست ترین فرهنگ لغت است. این به این دلیل اتفاق می افتد که پایتون شروع به اضافه کردن جفت های کلید-مقدار از چپ به راست می کند. اگر، در process، پایتون کلیدهایی را پیدا می کند که قبلاً خارج شده اند، سپس مفسر آن کلیدها را با مقدار جدید به روز می کند. به همین دلیل است که ارزش a
کلید در مثال بالا با حروف کوچک است.
باز کردن بسته بندی در For-Loops
همچنین میتوانیم از باز کردن بستهبندی تکرارپذیر در زمینه استفاده کنیم for
حلقه ها وقتی ما اجرا می کنیم for
حلقه، حلقه در هر تکرار یک مورد از تکرارپذیر خود را به متغیر هدف اختصاص می دهد. اگر موردی که باید تخصیص داده شود تکرارپذیر باشد، می توانیم از a استفاده کنیم tuple
از متغیرهای هدف حلقه تکراری که در دست است را در داخل باز می کند tuple
از متغیرهای هدف
به عنوان مثال، فرض کنید فایلی حاوی دادههای مربوط به فروش یک شرکت به شرح زیر داریم:
تولید – محصول | قیمت | واحدهای فروخته شده |
---|---|---|
مداد | 0.25 | 1500 |
نوت بوک | 1.30 | 550 |
پاک کن | 0.75 | 1000 |
… | … | … |
از این جدول می توانیم یک بسازیم list
از تاپل های دو عنصری هر یک tuple
شامل نام محصول، قیمت و واحدهای فروخته شده خواهد بود. با این اطلاعات می خواهیم درآمد هر محصول را محاسبه کنیم. برای این کار می توانیم از a استفاده کنیم for
حلقه مانند این:
>>> sales = (("Pencil", 0.22, 1500), ("Notebook", 1.30, 550), ("Eraser", 0.75, 1000))
>>> for item in sales:
... print(f"Income for {item(0)} is: {item(1) * item(2)}")
...
Income for Pencil is: 330.0
Income for Notebook is: 715.0
Income for Eraser is: 750.0
این کد همانطور که انتظار می رود کار می کند. با این حال، ما از شاخص ها برای دسترسی به عناصر جداگانه هر یک استفاده می کنیم tuple
. خواندن و درک این موضوع برای توسعه دهندگان تازه وارد ممکن است دشوار باشد.
بیایید نگاهی به پیاده سازی جایگزین با استفاده از unpacking در پایتون بیندازیم:
>>> for product, price, sold_units in sales:
... print(f"Income for {product} is: {price * sold_units}")
...
Income for Pencil is: 330.0
Income for Notebook is: 715.0
Income for Eraser is: 750.0
ما در حال حاضر از باز کردن بسته بندی تکرارپذیر در خود استفاده می کنیم for
حلقه این باعث می شود کد ما خواناتر و قابل نگهداری تر باشد زیرا ما از نام های توصیفی برای شناسایی عناصر هر کدام استفاده می کنیم tuple
. این تغییر کوچک به یک توسعه دهنده تازه وارد اجازه می دهد تا به سرعت منطق پشت کد را درک کند.
همچنین امکان استفاده از *
اپراتور در a for
حلقه برای بسته بندی چندین آیتم در یک متغیر هدف واحد:
>>> for first, *rest in ((1, 2, 3), (4, 5, 6, 7)):
... print("First:", first)
... print("Rest:", rest)
...
First: 1
Rest: (2, 3)
First: 4
Rest: (5, 6, 7)
در این for
حلقه، ما اولین عنصر هر دنباله را می گیریم first
. سپس *
اپراتور a را می گیرد list
مقادیر در متغیر هدف آن rest
.
در نهایت، ساختار متغیرهای هدف باید با ساختار تکرارپذیر مطابقت داشته باشد. در غیر این صورت با خطا مواجه خواهیم شد. به مثال زیر توجه کنید:
>>> data = (((1, 2), 2), ((2, 3), 3))
>>> for (a, b), c in data:
... print(a, b, c)
...
1 2 2
2 3 3
>>> for a, b, c in data:
... print(a, b, c)
...
Traceback (most recent call last):
...
ValueError: not enough values to unpack (expected 3, got 2)
در حلقه اول، ساختار متغیرهای هدف، (a, b), c
، با ساختار موارد در تکرار پذیر موافق است، ((1, 2), 2)
. در این مورد، حلقه همانطور که انتظار می رود کار می کند. در مقابل، حلقه دوم از ساختاری از متغیرهای هدف استفاده میکند که با ساختار آیتمهای تکرارپذیر مطابقت ندارند، بنابراین حلقه شکست میخورد و یک عدد را افزایش میدهد. ValueError
.
بسته بندی و باز کردن بسته بندی در توابع
همچنین میتوانیم از ویژگیهای بستهبندی و بازگشایی پایتون در هنگام تعریف و فراخوانی توابع استفاده کنیم. این یک مورد بسیار مفید و محبوب برای بسته بندی و باز کردن بسته بندی در پایتون است.
در این بخش، ما اصول اولیه روش استفاده از بسته بندی و باز کردن بسته بندی در توابع پایتون را در تعریف تابع یا در فراخوانی تابع پوشش خواهیم داد.
توجه داشته باشید: برای مطالب روشن تر و دقیق تر روی با این موضوعات، آرگومان های با طول متغیر در پایتون را بررسی کنید *args
و **kwargs
.
تعریف توابع با * و **
ما می توانیم استفاده کنیم *
و **
عملگرها در امضای توابع پایتون این به ما امکان می دهد تا تابع را با تعداد متغیری از آرگومان های موقعیتی فراخوانی کنیم (*
) یا با تعداد متغیری از آرگومان های کلیدواژه یا هر دو. بیایید تابع زیر را در نظر بگیریم:
>>> def func(required, *args, **kwargs):
... print(required)
... print(args)
... print(kwargs)
...
>>> func("Welcome to...", 1, 2, 3, site='rasanegar.com')
Welcome to...
(1, 2, 3)
{'site': 'rasanegar.com'}
تابع فوق حداقل به یک آرگومان فراخوانی شده نیاز دارد required
. می تواند تعداد متغیری از آرگومان های موقعیتی و کلیدواژه را نیز بپذیرد. در این مورد، *
عملگر آرگومان های موقعیتی اضافی را در یک تاپل به نام جمع آوری یا بسته بندی می کند args
و **
اپراتور آرگومان های کلیدواژه اضافی را در دیکشنری به نام جمع آوری یا بسته بندی می کند kwargs
. هر دو، args
و kwargs
، اختیاری هستند و به طور خودکار پیش فرض هستند ()
و {}
به ترتیب.
حتی اگر نام ها args
و kwargs
به طور گسترده توسط جامعه پایتون استفاده می شود، آنها برای کار کردن این تکنیک ها الزامی نیستند. نحو فقط نیاز دارد *
یا **
به دنبال آن یک شناسه معتبر بنابراین، اگر میتوانید نامهای معنیداری برای این استدلالها بگذارید، این کار را انجام دهید. این مطمئناً خوانایی کد شما را بهبود می بخشد.
فراخوانی توابع با * و **
هنگام فراخوانی توابع، می توانیم از استفاده از آن نیز بهره مند شویم *
و **
عملگر برای باز کردن مجموعهای از آرگومانها به ترتیب در آرگومانهای موقعیتی یا کلیدواژه جداگانه. این برعکس استفاده است *
و **
در امضای یک تابع در امضا، اپراتورها به معنای جمع آوری یا بسته بندی تعداد متغیری از آرگومان ها در یک شناسه. در تماس منظورشان است باز کردن بسته بندی قابل تکرار در چندین آرگومان
در اینجا یک مثال اساسی از روش کار این است:
>>> def func(welcome, to, site):
... print(welcome, to, site)
...
>>> func(*("Welcome", "to"), **{"site": 'rasanegar.com'})
Welcome to rasanegar.com
اینجا *
اپراتور توالی هایی مانند ("Welcome", "to")
به استدلال های موضعی به طور مشابه، **
اپراتور دیکشنری ها را به آرگومان هایی باز می کند که نام آنها با کلیدهای فرهنگ لغت بسته نشده مطابقت دارد.
همچنین میتوانیم این تکنیک و تکنیکی که در بخش قبل توضیح داده شد را برای نوشتن توابع کاملاً انعطافپذیر ترکیب کنیم. در اینجا یک مثال است:
>>> def func(required, *args, **kwargs):
... print(required)
... print(args)
... print(kwargs)
...
>>> func("Welcome to...", *(1, 2, 3), **{"site": 'rasanegar.com'})
Welcome to...
(1, 2, 3)
{'site': 'rasanegar.com'}
استفاده از *
و **
اپراتورها هنگام تعریف و فراخوانی توابع پایتون، قابلیتهای بیشتری به آنها میدهند و آنها را انعطافپذیرتر و قدرتمندتر میکنند.
نتیجه
باز کردن مجدد بسته بندی معلوم می شود که یک ویژگی بسیار مفید و محبوب در پایتون است. این ویژگی به ما این امکان را می دهد که یک قابل تکرار را در چندین متغیر باز کنیم. از سوی دیگر، بسته بندی شامل گرفتن چندین مقدار در یک متغیر با استفاده از عملگر unpacking است. *
.
در این آموزش، ما یاد گرفتیم که چگونه از unpacking تکرارپذیر در پایتون برای نوشتن کدهای خوانا، قابل نگهداری و پایتونیک تر استفاده کنیم.
با این دانش، اکنون میتوانیم از بستهبندی تکرارپذیر در پایتون برای حل مشکلات رایج مانند تخصیص موازی و جابجایی مقادیر بین متغیرها استفاده کنیم. ما همچنین می توانیم از این ویژگی پایتون در ساختارهای دیگری مانند for
حلقه ها، فراخوانی تابع، و تعاریف تابع.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-17 17:37:03