درس ۰۸: ساختمان‌های داده در پایتون: set و dict

درس ۰۸: ساختمان‌های داده در پایتون: set و dict

Photo by Natalia Y

از درس هفتم با انواع داده پایه در پایتون آشنا شده‌ایم و در این درس به بررسی انواع داده دیگری خواهیم پرداخت که در زبان‌های برنامه‌نویسی عموما با عنوان ساختمان‌های داده بیان می‌شوند. ساختمان‌های داده یا Data Structures به اشیایی گفته می‌شود که برای نگهداری از یک مجموعه داده طراحی شده‌اند و هر یک دارای ویژگی منحصربه‌فرد خود است. برای مثال قابل تغییر بودن، امکان حفظ ترتیب اعضا، امکان نگهداری داده‌های تکراری یا تنها اجبار به نگهداری داده‌های یکتا که هر یک مناسب وضعیت خاصی در برنامه‌نویسی هستند. این درس به بررسی چهار ساختمان داده متداول در پایتون خواهد پرداخت: لیست (list)، توپِل (tuple)، مجموعه (set) و دیکشنری (dict)

این بخش در ادامه شرح «لیست» و «توپِل» به شرح دو نوع دیگر از ساختمان‌های داده در پایتون می‌پردازد: «مجموعه» و «دیکشنری»

سطح: مقدماتی



دیکشنری

یکی دیگر از انواع ساختمان‌های داده در پایتون «دیکشنری» (Dictionary) می‌باشد که با نام کوتاه شده dict ارایه شده است. اشیا نوع دیکشنری با استفاده از نماد آکولاد { } معرفی‌ می‌شوند و هر داده در آن به شکل یک جفت «کلید:مقدار» (key:value) ذخیره می‌گردد. از این نوع شی با عنوان شی mapping (نگاشت) پایتون نیز یاد می‌شود چرا که در این نوع هر شی «کلید» به یک شی «مقدار» map یا نگاشت داده می‌شود. شی دیکشنری دنباله نیست و هر عضو آن به جای اندیس با استفاده از کلید دستیابی می‌شود. دیکشنری در پایتون تغییر پذیر است و شی «مقدار» می‌تواند از هر نوعی باشد حتی یک شی دیکشنری دیگر ولی شی «کلید» تنها می‌بایست از انواع «تغییرناپذیر» انتخاب شود و باید توجه داشت که تمام «کلید»‌های یک شی دیکشنری می‌بایست «یکتا» (Unique) باشند. از نسخه 3.7 پایتون، دیکشنری قابلیت حفظ ترتیب عناصر خود را نیز دارد یا به اصطلاح Ordered است.

>>> d = {1:'One', 2:'Two', 3:'Three'}

>>> type(d)
<class 'dict'>

>>> 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 "<stdin>", line 1, in <module>
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'}

عملگرها برای دیکشنری

عملگرهای + و * برای اشیا دیکشنری تعریف نشده‌اند.

از عملگرهای عضویت می‌توان برای بررسی وجود یک کلید در شی دیکشنری استفاده کرد:

>>> 'job' in {'name': 'Bob', 'age': 40}
False

>>> 'job' not in {'name': 'Bob', 'age': 40}
True

در مورد عملکرد عملگر برابری == و عملگرهای هویت (is و is not) صحبت شده است؛ این عملگرها برای اشیا دیکشنری نیز کاربرد دارند.

کپی کردن

همانطور که گفته شد شی دیکشنری از انواع «تغییر پذیر» پایتون است و همان توضیحاتی که در مورد شی لیست بیان شد؛ در اینجا هم درست است و گاهی نیاز می‌شود که از ماژول 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']}
    

تبدیل به شی دیکشنری

برای تبدیل دیگر اشیا به نوع دیکشنری یا در کل ایجاد شی دیکشنری از کلاس ()dict [اسناد پایتون] استفاده می‌شود.

برای تبدیل اشیا دنباله به مانند لیست و توپِل به دیکشنری می‌بایست از ساختار تودرتو استفاده کرد، به گونه‌ای که هر عضو این ساختمان‌ها خود شامل دو عضو باشد:

>>> t = ('one', 'two', 'three')
>>> type(t)
<class 'tuple'>

>>> d = dict(t)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
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
<zip object at 0x7eff1d263548>

>>> type(z)
<class 'zip'>

>>> 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 استفاده خواهیم کرد.

برخی از متدهای کاربردی یک شی دیکشنری

  • ()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 "<stdin>", line 1, in <module>
    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 را می‌توان با استفاده از کلاس ()set [اسناد پایتون] یا تنها با استفاده از نماد آکولاد { } ایجاد کرد:

>>> L = [1, 2, 3, 4, 5]

>>> s = set(L)

>>> type(s)
<class 'set'>

>>> s
{1, 2, 3, 4, 5}

>>> print(s)
{1, 2, 3, 4, 5}
>>> s = {1, 2, 3, 4, 5}

>>> type(s)
<class 'set'>

>>> s
{1, 2, 3, 4, 5}

هیچ سینتکس خاصی برای ایجاد یا بیان یک شی خالی از نوع مجموعه وجود ندارد و تنها می‌بایست از کلاس ()set - بدون آرگومان - استفاده کرد. توجه داشته باشید که {} بیانگر یک شی دیکشنری خالی است و نه یک مجموعه خالی:

>>> a = {}
>>> type(a)
<class 'dict'>

>>> b = set()
>>> type(b)
<class 'set'>

>>> b
set()

از تابع ()len می‌توان برای به دست آوردن تعداد عضوهای یک شی مجموعه نیز استفاده کرد:

>>> s = {1, 2, 3, 4, 5}
>>> len(s)
5

عملگرها برای مجموعه

تعدادی از عملگرها هستند که برای اشیا مجموعه تعریف خاصی پیدا می‌کنند؛ در حالی که در مورد اشیا دیگر چنین رفتاری ندارند. این عملگرها در واقع پیاده‌سازی تعریف مشخصی در مفهوم ریاضی مجموعه‌ها هستند:

  • | اجتماع (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

برخی از متدهای کاربردی یک شی مجموعه

  • ()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 "<stdin>", line 1, in <module>
    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 "<stdin>", line 1, in <module>
    KeyError: 'pop from an empty set'
    

frozenset

همانطور که پیش از این بیان شد مجموعه یک شی «تغییر پذیر» است با عضوهای «تغییر ناپذیر» و به دلیل همین تغییر پذیری است که می‌توانیم به سادگی توسط متدهایش، عضوی به آن افزوده یا حذف نماییم. ”frozenset“ یک نوع جدید مجموعه است. همانگونه که می‌توانیم یک شی توپِل را معادل یک شی لیست تغییر ناپذیر تصویر کنیم؛ frozenset را نیز می‌توان یک شی مجموعه تغییر ناپذیر تصور کرد. نوع frozenset همان نوع set است، با تمام ویژگی‌های آن به غیر از تغییر پذیری که با استفاده از کلاس ()frozenset ایجاد می‌گردد:

>>> L =[1, 2, 3]

>>> A = frozenset(L)

>>> type(A)
<class 'frozenset'>

>>> 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):

    1- int
    2- float
    3- complex
    4- Decimal
    5- Fraction
    6- bool
    
  • انواع متنی (Text Types):

    1- str
    
  • انواع باینری (Binary Types):

    1- bytes
    2- bytearray
    
  • انواع دنباله (Sequence Types):

    1- str
    2- bytes
    3- bytearray
    4- tuple
    5- list
    
  • انواع تغییرناپذیر (Immutable Types):

     1- int
     2- float
     3- complex
     4- Decimal
     5- Fraction
     6- bool
     7- str
     8- bytes
     9- tuple
    10- frozenset
    
  • انواع تغییرپذیر (Mutable Types):

    1- bytearray
    2- list
    3- dict
    4- set
    
  • انواع نگاشت (Mapping Types):

    1- dict
    
  • انواع مجموعه (Set Types):

    1- set
    2- frozenset
    
  • برخی دیگر:

    1- zip
    2- NoneType
    


😊 امیدوارم مفید بوده باشه