آموزش پایتون, پایتون سطح متوسط

مجموعه یا Set در پایتون؛ حذف مقادیر تکراری و عملیات مجموعه‌ها

مجموعه یا Set در پایتون

🗓 آخرین به‌روزرسانی:

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

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

Set در پایتون چیست؟

Set مجموعه‌ای بدون اندیس از مقادیر یکتا است. عناصر یک Set معمولاً داخل آکولاد نوشته می‌شوند:

languages = {"Python", "JavaScript", "PHP"}
print(languages)

ترتیب نمایش عناصر ممکن است با ترتیب نوشته‌شدن آن‌ها متفاوت باشد. به همین دلیل نباید برای دسترسی به عناصر Set روی ترتیب ثابت حساب کنیم.

ویژگی‌های اصلی مجموعه‌ها

  • عناصر یکتا هستند: مقدار تکراری فقط یک بار نگهداری می‌شود.
  • بدون اندیس هستند: نمی‌توان مانند لیست با شماره جایگاه به عناصر دسترسی داشت.
  • ترتیب قابل اتکا ندارند: ترتیب نمایش عناصر تضمین‌شده نیست.
  • قابل تغییر هستند: می‌توان عنصر اضافه یا حذف کرد.
  • عناصر باید قابل هش باشند: رشته، عدد و تاپل مناسب‌اند؛ اما لیست و دیکشنری نمی‌توانند عنصر مستقیم Set باشند.
  • برای بررسی عضویت مناسب‌اند: استفاده از in روی Set معمولاً سریع و خواناست.

ساخت Set در پایتون

برای ساخت مجموعه می‌توان از آکولاد استفاده کرد:

numbers = {10, 20, 30, 40}
print(numbers)
print(type(numbers))

خروجی نوع داده:

<class 'set'>

حذف خودکار مقادیر تکراری

اگر یک مقدار چند بار در Set نوشته شود، فقط یک نسخه از آن باقی می‌ماند:

numbers = {10, 20, 20, 30, 30, 30}
print(numbers)

خروجی شامل سه مقدار یکتاست:

{10, 20, 30}

این ویژگی یکی از مهم‌ترین کاربردهای Set است.

ساخت Set خالی؛ یک نکته بسیار مهم

برای ساخت Set خالی نباید از آکولاد خالی استفاده کنیم؛ زیرا {} یک دیکشنری خالی می‌سازد:

empty_data = {}
print(type(empty_data))

خروجی:

<class 'dict'>

روش صحیح ساخت مجموعه خالی استفاده از تابع set() است:

empty_set = set()
print(type(empty_set))

ساخت مجموعه با تابع set

تابع set() می‌تواند یک داده قابل پیمایش را به مجموعه تبدیل کند:

letters = set("Python")
print(letters)

هر حرف فقط یک بار در مجموعه قرار می‌گیرد و ترتیب نمایش قابل پیش‌بینی نیست.

تبدیل لیست به Set برای حذف تکرارها

names = ["علی", "سارا", "علی", "رضا", "سارا"]
unique_names = set(names)

print(unique_names)

اگر خروجی را دوباره به لیست نیاز داشته باشیم:

unique_names_list = list(set(names))

توجه کنید که این روش ترتیب اولیه لیست را حفظ نمی‌کند.

حذف تکرارها با حفظ ترتیب

اگر حفظ ترتیب اهمیت دارد، استفاده از دیکشنری مناسب‌تر است:

names = ["علی", "سارا", "علی", "رضا", "سارا"]
unique_names = list(dict.fromkeys(names))

print(unique_names)

خروجی:

['علی', 'سارا', 'رضا']

چه نوع داده‌هایی می‌توانند عضو Set باشند؟

عناصر Set باید غیرقابل‌تغییر و قابل هش باشند. نمونه‌های معتبر:

data = {
    "Python",
    100,
    18.5,
    True,
    (35.7, 51.4)
}

لیست نمی‌تواند عضو Set باشد:

data = {[1, 2, 3]}

این کد خطای زیر را ایجاد می‌کند:

TypeError: unhashable type: 'list'

مقادیر True، False، 1 و 0 در Set

در پایتون، مقدار True از نظر برابری با عدد 1 و مقدار False با عدد 0 برابر است. بنابراین ممکن است همه آن‌ها به‌صورت جداگانه در Set باقی نمانند:

values = {True, 1, False, 0}
print(values)

خروجی معمولاً فقط دو عضو خواهد داشت.

Set اندیس ندارد

نمی‌توان با اندیس به عنصر یک مجموعه دسترسی داشت:

colors = {"قرمز", "سبز", "آبی"}
print(colors[0])

این کد خطای زیر را ایجاد می‌کند:

TypeError: 'set' object is not subscriptable

برای پردازش عناصر باید از حلقه استفاده کنیم یا Set را به لیست تبدیل کنیم.

پیمایش Set با حلقه for

skills = {"Python", "Git", "SQL"}

for skill in skills:
    print(skill)

ترتیب چاپ عناصر ممکن است در اجراهای مختلف متفاوت باشد.

بررسی وجود یک مقدار با in

allowed_users = {"ali", "sara", "reza"}

if "sara" in allowed_users:
    print("کاربر مجاز است")

بررسی نبودن مقدار

if "mehdi" not in allowed_users:
    print("کاربر در فهرست مجاز نیست")

تعداد عناصر Set با len

tags = {"python", "web", "api"}
print(len(tags))

خروجی:

3

افزودن یک عنصر با add

متد add() یک عنصر جدید به مجموعه اضافه می‌کند:

skills = {"Python", "Git"}
skills.add("SQL")

print(skills)

اگر مقدار از قبل وجود داشته باشد، مجموعه تغییر نمی‌کند:

skills.add("Python")

افزودن چند عنصر با update

متد update() عناصر یک یا چند داده قابل پیمایش را به Set اضافه می‌کند:

skills = {"Python"}
skills.update(["Git", "SQL"], {"Docker", "Linux"})

print(skills)

تفاوت add و update

  • add() یک عنصر را اضافه می‌کند.
  • update() عناصر یک داده قابل پیمایش را جداگانه اضافه می‌کند.
letters = {"A"}
letters.update("BC")
print(letters)

حروف B و C جداگانه اضافه می‌شوند.

حذف عنصر با remove

colors = {"قرمز", "سبز", "آبی"}
colors.remove("سبز")

print(colors)

اگر مقدار وجود نداشته باشد، remove() خطای KeyError ایجاد می‌کند:

colors.remove("زرد")

حذف امن با discard

متد discard() مانند remove() مقدار را حذف می‌کند؛ اما اگر مقدار وجود نداشته باشد خطایی ایجاد نمی‌شود:

colors = {"قرمز", "سبز", "آبی"}
colors.discard("زرد")

print(colors)

حذف یک عنصر با pop

متد pop() یک عنصر دلخواه را حذف و برمی‌گرداند:

colors = {"قرمز", "سبز", "آبی"}
removed_color = colors.pop()

print("حذف شد:", removed_color)
print(colors)

چون Set ترتیب قابل اتکا ندارد، نباید فرض کنیم کدام عنصر حذف می‌شود.

خالی‌کردن Set با clear

numbers = {1, 2, 3}
numbers.clear()

print(numbers)

خروجی:

set()

حذف کامل متغیر با del

numbers = {1, 2, 3}
del numbers

پس از اجرای del، خود متغیر دیگر وجود ندارد.

اجتماع دو مجموعه با union

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

backend = {"Python", "Django", "SQL"}
frontend = {"HTML", "CSS", "JavaScript", "Python"}

all_skills = backend.union(frontend)
print(all_skills)

همین عملیات با عملگر | نیز انجام می‌شود:

all_skills = backend | frontend

اشتراک دو مجموعه با intersection

اشتراک شامل اعضایی است که در هر دو مجموعه وجود دارند:

backend = {"Python", "Django", "SQL"}
frontend = {"HTML", "CSS", "JavaScript", "Python"}

common_skills = backend.intersection(frontend)
print(common_skills)

خروجی:

{'Python'}

عملگر معادل:

common_skills = backend & frontend

تفاضل دو مجموعه با difference

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

backend = {"Python", "Django", "SQL"}
frontend = {"HTML", "CSS", "JavaScript", "Python"}

only_backend = backend.difference(frontend)
print(only_backend)

خروجی:

{'Django', 'SQL'}

عملگر معادل:

only_backend = backend - frontend

جهت تفاضل مهم است:

print(frontend - backend)

تفاضل متقارن با symmetric_difference

تفاضل متقارن شامل اعضایی است که فقط در یکی از دو مجموعه وجود دارند، نه در هر دو:

first = {1, 2, 3, 4}
second = {3, 4, 5, 6}

result = first.symmetric_difference(second)
print(result)

خروجی:

{1, 2, 5, 6}

عملگر معادل:

result = first ^ second

متدهای به‌روزرسانی مجموعه

متدهای زیر نتیجه عملیات را مستقیماً در مجموعه اصلی ذخیره می‌کنند:

intersection_update

first = {1, 2, 3, 4}
second = {3, 4, 5}

first.intersection_update(second)
print(first)

مجموعه first فقط شامل اشتراک می‌شود.

difference_update

first = {1, 2, 3, 4}
second = {3, 4, 5}

first.difference_update(second)
print(first)

symmetric_difference_update

first = {1, 2, 3, 4}
second = {3, 4, 5}

first.symmetric_difference_update(second)
print(first)

بررسی زیرمجموعه با issubset

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

required_skills = {"Python", "Git"}
user_skills = {"Python", "Git", "SQL", "Docker"}

print(required_skills.issubset(user_skills))

خروجی:

True

عملگر معادل:

print(required_skills <= user_skills)

بررسی ابرمجموعه با issuperset

print(user_skills.issuperset(required_skills))

عملگر معادل:

print(user_skills >= required_skills)

زیرمجموعه و ابرمجموعه حقیقی

عملگرهای < و > بررسی می‌کنند که علاوه بر رابطه زیرمجموعه، دو مجموعه برابر نباشند:

small = {1, 2}
large = {1, 2, 3}

print(small < large)
print(large > small)

بررسی جدا بودن دو مجموعه با isdisjoint

اگر دو مجموعه هیچ عضو مشترکی نداشته باشند، isdisjoint() مقدار True برمی‌گرداند:

weekdays = {"شنبه", "یکشنبه", "دوشنبه"}
holidays = {"پنجشنبه", "جمعه"}

print(weekdays.isdisjoint(holidays))

کپی‌کردن Set

original = {1, 2, 3}
copy_set = original.copy()

copy_set.add(4)

print(original)
print(copy_set)

مقایسه Set با List و Tuple

ویژگیSetListTuple
ترتیب قابل اتکاخیربلهبله
اندیس‌گذاریخیربلهبله
مقادیر تکراریخیربلهبله
قابل تغییربلهبلهخیر
عملیات اجتماع و اشتراکبلهمستقیم نداردمستقیم ندارد
کاربرد اصلیعضویت و یکتاسازیفهرست مرتب و قابل تغییرداده مرتب و ثابت

Frozenset در پایتون چیست؟

frozenset نسخه غیرقابل‌تغییر Set است. پس از ساخت نمی‌توان عضو جدیدی به آن اضافه یا عضوی را حذف کرد:

permissions = frozenset(["read", "write"])
print(permissions)

کد زیر معتبر نیست:

permissions.add("delete")

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

groups = {
    frozenset(["Python", "Django"]),
    frozenset(["HTML", "CSS"])
}

Set Comprehension

مانند لیست و دیکشنری، می‌توان Set را با عبارت فشرده ساخت:

squares = {number ** 2 for number in range(1, 6)}
print(squares)

ساخت مجموعه اعداد زوج

even_numbers = {
    number
    for number in range(1, 21)
    if number % 2 == 0
}

print(even_numbers)

پروژه اول: مقایسه مهارت‌های کاربر با یک موقعیت شغلی

در این پروژه، مهارت‌های لازم برای یک شغل را با مهارت‌های کاربر مقایسه می‌کنیم:

required_skills = {
    "Python",
    "Git",
    "SQL",
    "Django"
}

user_skills = {
    "Python",
    "Git",
    "HTML"
}

matched_skills = required_skills & user_skills
missing_skills = required_skills - user_skills
extra_skills = user_skills - required_skills

print("مهارت‌های مشترک:", matched_skills)
print("مهارت‌های موردنیاز:", missing_skills)
print("مهارت‌های اضافه:", extra_skills)

if required_skills <= user_skills:
    print("کاربر تمام مهارت‌های لازم را دارد.")
else:
    print("کاربر باید مهارت‌های باقی‌مانده را یاد بگیرد.")

پروژه دوم: تحلیل ثبت‌نام دو دوره

python_students = {
    "علی",
    "سارا",
    "رضا",
    "مریم"
}

web_students = {
    "سارا",
    "مریم",
    "حسین",
    "نگار"
}

all_students = python_students | web_students
both_courses = python_students & web_students
only_python = python_students - web_students
only_one_course = python_students ^ web_students

print("همه دانشجویان:", all_students)
print("شرکت‌کنندگان هر دو دوره:", both_courses)
print("فقط دوره پایتون:", only_python)
print("فقط یکی از دوره‌ها:", only_one_course)

پروژه سوم: دریافت برچسب‌های یکتا از کاربر

tags = set()

while True:
    tag = input("برچسب را وارد کنید یا exit بنویسید: ").strip().lower()

    if tag == "exit":
        break

    if not tag:
        print("برچسب خالی معتبر نیست.")
        continue

    before_count = len(tags)
    tags.add(tag)

    if len(tags) == before_count:
        print("این برچسب قبلاً ثبت شده است.")
    else:
        print("برچسب اضافه شد.")

print("برچسب‌های یکتا:")
for tag in sorted(tags):
    print("-", tag)

برای نمایش مرتب از sorted() استفاده شده است؛ خروجی این تابع یک لیست مرتب است.

خطاهای رایج هنگام کار با Set

۱. استفاده از آکولاد خالی برای Set

items = {}  # دیکشنری است

نسخه صحیح:

items = set()

۲. تلاش برای اندیس‌گذاری

numbers = {1, 2, 3}
print(numbers[0])  # نادرست

۳. افزودن لیست به Set

data = set()
data.add([1, 2])  # TypeError

می‌توان به‌جای لیست از تاپل استفاده کرد:

data.add((1, 2))

۴. استفاده از remove برای مقدار ناموجود

colors.remove("زرد")  # احتمال KeyError

برای حذف بدون خطا:

colors.discard("زرد")

۵. وابستگی به ترتیب عناصر

Set برای داده‌های مرتب مناسب نیست. در صورت نیاز به ترتیب، از List یا Tuple استفاده کنید.

۶. اشتباه در جهت تفاضل

first - second

با عبارت second - first نتیجه متفاوتی دارد.

تمرین‌های پیشنهادی

  1. یک لیست شامل نام‌های تکراری بسازید و تعداد نام‌های یکتا را محاسبه کنید.
  2. دو Set از رنگ‌ها بسازید و اجتماع، اشتراک و تفاضل آن‌ها را نمایش دهید.
  3. برنامه‌ای بنویسید که عددهای تکراری ورودی را حذف کند.
  4. دو مجموعه از فیلم‌های دیده‌شده توسط دو کاربر بسازید و فیلم‌های مشترک را پیدا کنید.
  5. بررسی کنید آیا مجموعه مجوزهای یک کاربر شامل تمام مجوزهای لازم است.
  6. با isdisjoint() بررسی کنید دو گروه دانش‌آموز عضو مشترک دارند یا خیر.
  7. یک Set Comprehension برای مکعب عددهای ۱ تا ۱۰ بسازید.
  8. برنامه‌ای بسازید که کلمات یکتای یک جمله را محاسبه کند.
  9. مهارت‌های مشترک و متفاوت دو برنامه‌نویس را گزارش کنید.
  10. یک frozenset از روزهای تعطیل بسازید و تلاش برای تغییر آن را آزمایش کنید.

📌 همچنین بخوانید: بازار کار پایتون در ایران، دستورهای break، continue و pass در پایتون و ساخت ربات تلگرام با پایتون

پرسش‌های متداول

آیا Set ترتیب عناصر را حفظ می‌کند؟

نباید روی ترتیب عناصر Set تکیه کرد. برای خروجی مرتب می‌توان از sorted() استفاده کرد.

آیا Set مقدار تکراری می‌پذیرد؟

خیر. هر مقدار برابر فقط یک بار در مجموعه نگهداری می‌شود.

تفاوت remove و discard چیست؟

اگر مقدار وجود نداشته باشد، remove() خطای KeyError ایجاد می‌کند؛ اما discard() بدون خطا ادامه می‌دهد.

آیا می‌توان یک لیست را عضو Set کرد؟

خیر؛ زیرا لیست قابل تغییر و غیرقابل هش است. در صورت مناسب‌بودن ساختار، می‌توان آن را به تاپل تبدیل کرد.

بهترین کاربرد Set چیست؟

حذف تکرارها، بررسی سریع عضویت، یافتن اشتراک و تفاوت چند گروه داده و تحلیل رابطه زیرمجموعه‌ها از مهم‌ترین کاربردهای Set هستند.

تفاوت set و frozenset چیست؟

set قابل تغییر است؛ اما frozenset پس از ساخت تغییر نمی‌کند و می‌تواند به‌عنوان کلید دیکشنری یا عضو Set دیگر استفاده شود.

جمع‌بندی

در این درس با ساخت Set، حذف خودکار مقادیر تکراری، بررسی عضویت، افزودن و حذف عناصر، اجتماع، اشتراک، تفاضل، تفاضل متقارن، زیرمجموعه، ابرمجموعه، frozenset و Set Comprehension آشنا شدیم. مجموعه‌ها زمانی بهترین انتخاب هستند که یکتا بودن داده و عملیات رابطه‌ای بین چند گروه اهمیت داشته باشد.

درس بعدی: توابع در پایتون؛ تعریف تابع با def و استفاده از return.

ادامه مسیر یادگیری پایتون

برای یادگیری منظم، آموزش‌های مرتبط زیر را به‌ترتیب دنبال کنید:

می‌خواهی پیشرفتت ذخیره شود؟با ورود یا ثبت‌نام رایگان، درس‌های تمام‌شده را علامت بزن و درصد پیشرفتت را در حساب کاربری ببین.ورود / ثبت‌نام برای ذخیره پیشرفت
درس بعدی · دوره پایتون متوسط (4 از 18)توابع در پایتون؛ تعریف تابع با def و استفاده از return ←
آموزش‌های تازه، کد آماده و رفع خطاهر هفته در کانال Dev Source؛ رایگان.
🧭 مسیر یادگیری پایتون از صفر
ماژول 5: ساختارهای داده — درس 21 از 44

برای ذخیره پیشرفت در همه دستگاه‌ها و دریافت گواهی پایان مسیر، رایگان ثبت‌نام کن یا وارد شو.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *