مجموعه یا 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
| ویژگی | Set | List | Tuple |
|---|---|---|---|
| ترتیب قابل اتکا | خیر | بله | بله |
| اندیسگذاری | خیر | بله | بله |
| مقادیر تکراری | خیر | بله | بله |
| قابل تغییر | بله | بله | خیر |
| عملیات اجتماع و اشتراک | بله | مستقیم ندارد | مستقیم ندارد |
| کاربرد اصلی | عضویت و یکتاسازی | فهرست مرتب و قابل تغییر | داده مرتب و ثابت |
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 نتیجه متفاوتی دارد.
تمرینهای پیشنهادی
- یک لیست شامل نامهای تکراری بسازید و تعداد نامهای یکتا را محاسبه کنید.
- دو Set از رنگها بسازید و اجتماع، اشتراک و تفاضل آنها را نمایش دهید.
- برنامهای بنویسید که عددهای تکراری ورودی را حذف کند.
- دو مجموعه از فیلمهای دیدهشده توسط دو کاربر بسازید و فیلمهای مشترک را پیدا کنید.
- بررسی کنید آیا مجموعه مجوزهای یک کاربر شامل تمام مجوزهای لازم است.
- با
isdisjoint()بررسی کنید دو گروه دانشآموز عضو مشترک دارند یا خیر. - یک Set Comprehension برای مکعب عددهای ۱ تا ۱۰ بسازید.
- برنامهای بسازید که کلمات یکتای یک جمله را محاسبه کند.
- مهارتهای مشترک و متفاوت دو برنامهنویس را گزارش کنید.
- یک
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.
ادامه مسیر یادگیری پایتون
برای یادگیری منظم، آموزشهای مرتبط زیر را بهترتیب دنبال کنید:
برای ذخیره پیشرفت در همه دستگاهها و دریافت گواهی پایان مسیر، رایگان ثبتنام کن یا وارد شو.