تا

تاپل‌ها در Python

15 تمرین

درباره‌ی تاپل‌ها

یک تاپل مجموعه‌ای تغییرناپذیر از عناصر در دنباله است.

مانند بیشتر مجموعه‌ها (به list، dict و set توکار نگاه کنید)، tuples می‌تواند هر نوع داده (یا چند نوع داده) را در خود نگه دارد، از جمله tuplesهای دیگر. می‌توان عناصر یک تاپل را با ساختار for item in <tuple> پیمایش کرد. اگر هم اندیس عنصر و هم مقدار آن لازم باشد، می‌توان از for index, item in enumerate(<tuple>) استفاده کرد.

مانند هر دنباله دیگری، می‌توان به عناصر درون tuples از طریق نشانه‌گذاری براکت دسترسی پیدا کرد؛ با یک شماره‌ی 0-based index از سمت چپ یا یک شماره‌ی -1-based index از سمت راست. تاپل‌ها را می‌توان به‌صورت کامل یا جزئی از طریق نشانه‌گذاری برش یا <tuple>.copy() کپی کرد و از همه‌ی عملیات رایج دنباله پشتیبانی می‌کنند. تاپل‌ها چون تغییرناپذیر هستند، از عملیات دنباله‌ی تغییرپذیر پشتیبانی نمی‌کنند.

تاپل‌ها در مقایسه با سایر انواع مجموعه، فضای حافظه‌ی بسیار کمی اشغال می‌کنند و هنگام استفاده از اندیس، زمان دسترسی ثابت (O(1)) دارند. با این حال، پس از ساخته شدن نمی‌توان اندازه‌شان را تغییر داد، مرتبشان کرد یا آن‌ها را دستکاری کرد، بنابراین زمانی که تغییرات یا به‌روزرسانی‌های مکرر روی داده‌ها لازم باشد، انعطاف کمتری دارند. اگر به‌روزرسانی یا گسترش مکرر لازم باشد، list، collections.deque یا array.array ممکن است ساختار داده‌ی مناسب‌تری باشد.


ساخت تاپل

تاپل‌ها را می‌توان به روش‌های متعددی ساخت؛ یا با سازنده‌ی کلاس tuple یا با اعلان (<element_1>, <element_2>) (لیترال tuple).

استفاده از سازنده‌ی tuple() به‌صورت خالی یا با یک تکرارپذیر:

>>> no_elements = tuple()
()

# The constructor *requires* an iterable, so single elements must be passed in a list or another tuple.
>>> one_element = tuple([16])
(16,)

رشته‌ها تکرارپذیرند، بنابراین استفاده از یک str به‌عنوان آرگومان سازنده‌ی tuple() می‌تواند نتایج غافلگیرکننده‌ای داشته باشد:

# String elements (characters) are iterated through and added to the tuple
>>> multiple_elements_string = tuple("Timbuktu")
('T', 'i', 'm', 'b', 'u', 'k', 't', 'u')

در سایر تکرارپذیرها نیز عناصر یکی‌یکی اضافه می‌شوند:

>>> multiple_elements_list = tuple(["Parrot", "Bird", 334782])
("Parrot", "Bird", 334782)

>>> multiple_elements_set = tuple({2, 3, 5, 7, 11})
(2,3,5,7,11)

پیمایش پیش‌فرض برای dict روی کلیدها است. برای اینکه هم کلیدها و هم مقادیر در تاپلی ساخته‌شده از یک دیکشنری گنجانده شوند، از <dict>.items() استفاده کنید که یک تکرارگر از tuplesهای (key, value) برمی‌گرداند.

>>> source_data = {"fish": "gold", "monkey": "brown"}

>>> multiple_elements_dict_1 = tuple(source_data)
('fish', 'monkey')

>>> multiple_elements_dict_2 = tuple(source_data.items())
(('fish', 'gold'), ('monkey', 'brown'))
اعلان یک تاپل به‌صورت یک لیترال :

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

>>> no_elements = ()
()

>>> one_element = ("Guava",)
("Guava",)

توجه کنید که به‌طور کلی برای ساخت یک لیترال tuple، پرانتز لازم نیست و تنها کاما کافی است. با این حال، در بیشتر موقعیت‌ها استفاده از (<element_1>, <element_2>) خواناتر در نظر گرفته می‌شود. پرانتز همچنین در موارد مبهم لازم است، مانند تاپل خالی یا تک‌عنصری، یا جایی که یک تابع تاپل را به‌عنوان آرگومان می‌گیرد.

>>> elements_separated_with_commas = "Parrot", "Bird", 334782
("Parrot", "Bird", 334782)

>>> elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60)
("Triangle", 60, 60, 60)

ساختارهای داده‌ی دیگر را می‌توان به‌عنوان عناصر tuple گنجاند، از جمله tuplesهای دیگر.

>>> nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))
({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))

>>> nested_data_structures_1 = (["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))
(["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))

می‌توان تاپل‌ها را با عملگر به‌علاوه‌ی + به هم پیوند داد؛ این کار هر tuple را باز می‌کند و یک tuple ترکیبی جدید می‌سازد.

>>> new_via_concatenate = ("George", 5) + ("cat", "Tabby")
("George", 5, "cat", "Tabby")

#likewise, using the multiplication operator * is the equivalent of using + n times
>>> first_group = ("cat", "dog", "elephant")

>>> multiplied_group = first_group * 3
('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant')

دسترسی به داده

می‌توان به عناصر درون تاپل‌ها (مانند سایر انواع دنباله یعنی str و list) از طریق نشانه‌گذاری براکت دسترسی پیدا کرد. اندیس‌ها می‌توانند از left به right (شروع از صفر) یا از right به left (شروع از ۱-) باشند. همچنین می‌توان تاپل‌ها را به‌صورت کامل یا جزئی از طریق نشانه‌گذاری برش یا با استفاده از <tuple>.copy() کپی کرد.

>>> student_info = ("Alyssa", "grade 3", "female", 8)

#name is at index 0 or index -4
>>> student_name = student_info[0]
Alyssa

>>> student_name = student_info[-4]
Alyssa

#age is at index 3 or index -1
>>> student_age_1 = student_info[3]
8

>>> student_age_2 = student_info[-1]
8

پیمایش روی عناصر

می‌توان عناصر درون تاپل‌ها را با ساختار for item in <tuple> در یک حلقه پیمایش کرد. اگر هم اندیس‌ها و هم مقادیر لازم باشند، می‌توان از for index, item in enumerate(<tuple>) استفاده کرد.

>>> student_info = ("Alyssa", "grade 3", "female", 8)
>>> for item in student_info:
...   print(item)
...
Alyssa
grade 3
female
8

>>> for index, item in enumerate(student_info):
...  print("Index is: " + str(index) + ", value is: " + str(item) + ".")
...
Index is: 0, value is: Alyssa.
Index is: 1, value is: grade 3.
Index is: 2, value is: female.
Index is: 3, value is: 8.

تاپل به‌عنوان اطلاعات همگن

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

>>> student_info = ("Alyssa", "grade 3", "female", 8)

تاپل‌ها همچنین زمانی به کار می‌روند که دنباله‌های تغییرناپذیر و همگنی از داده برای hashability، ذخیره در یک set، یا ساخت کلیدها در یک دیکشنری لازم باشد.

توجه کنید که اگرچه tuples در بیشتر موارد تغییرناپذیر هستند، چون می‌توانند هر ساختار داده یا شیئی را در خود جای دهند، اگر هر یک از عناصرشان از یک نوع تغییرپذیر باشد، می‌توانند تغییرپذیر شوند. استفاده از یک نوع داده‌ی تغییرپذیر درون یک tuple باعث می‌شود tuple دربرگیرنده غیرقابل هش شود.

>>> cmyk_color_map = {
        (.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292),
        (0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01),
        (.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E),
        (0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C)
    }

>>> unique_rgb_colors = {
        (59, 178, 146),
        (247, 127, 1),
        (89, 16, 142),
        (140, 0, 76),
        (76, 0, 140)
     }

>>> teal_700 = hash((59, 178, 146))

>>> teal_700 = hash(("Pantone 228", [(140, 0, 76), 0x8C004C]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

تاپل‌های گسترده و انواع داده‌ی مرتبط

تاپل‌ها اغلب به‌عنوان رکورد به کار می‌روند، اما می‌توان به داده‌های درون آن‌ها فقط از طریق موقعیت/اندیس دسترسی پیدا کرد. کلاس namedtuple() در ماژول collections کارکرد پایه‌ی تاپل را گسترش می‌دهد تا امکان دسترسی به عناصر با اسم فراهم شود. علاوه بر این، کاربران می‌توانند یک dataclass را طوری تنظیم کنند که کارکرد مشابهی برای دسترسی به ویژگی‌ها با اسم ارائه دهد؛ این کار مزایا و معایبی دارد.

ویرایش از طریق GitHub این پیوند در پنجره یا زبانه‌ی جدیدی باز می‌شود

تاپل‌ها را یاد بگیرید

تمرین کردن قفل شده است

برای تمرین تاپل‌ها قفل 5 تمرین دیگر را باز کنید