একটি set হলো hashable অবজেক্টের একটি মিউটেবল ও আনঅর্ডার্ড কালেকশন।
সেটের সদস্যগুলো অবশ্যই আলাদা হতে হবে, ডুপ্লিকেট আইটেম রাখা যায় না।
এরা একাধিক ভিন্ন ডেটা টাইপ এবং এমনকি tuple-এর tuples-এর মতো নেস্টেড স্ট্রাকচারও ধারণ করতে পারে, শর্ত একটাই, সব এলিমেন্ট যেন hashable হয়।
সেটের একটি ইমিউটেবল frozenset রূপও আছে।
অন্য ডেটা স্ট্রাকচার বা আইটেমের গ্রুপিং থেকে দ্রুত ডুপ্লিকেট সরাতে সেট সবচেয়ে বেশি ব্যবহৃত হয়। সিকোয়েন্সিং আর ডুপ্লিকেট ট্র্যাকিংয়ের দরকার না থাকলে দক্ষ তুলনার জন্যও এগুলো ব্যবহার করা হয়।
অন্য কালেকশন টাইপের (ডিকশনারি, লিস্ট, টুপল) মতো sets যা সমর্থন করে:
for item in <set> দিয়ে ইটারেশন,in আর not in দিয়ে মেম্বারশিপ যাচাই,len() দিয়ে দৈর্ঘ্য নির্ণয়, এবংcopy() দিয়ে শ্যালো কপি।sets যা সমর্থন করে না:
+ দিয়ে কনক্যাটেনেশনএকটি set-এ মেম্বারশিপ যাচাইয়ের টাইম কমপ্লেক্সিটি (গড়ে) কনস্ট্যান্ট, অথচ list বা string-এ মেম্বারশিপ যাচাই করলে ডেটার দৈর্ঘ্য বাড়ার সাথে টাইম কমপ্লেক্সিটিও বাড়তে থাকে।
<set>.union(), <set>.intersection(), বা <set>.difference()-এর মতো মেথডগুলোরও টাইম কমপ্লেক্সিটি (গড়ে) কনস্ট্যান্ট।
সেট নানা ভিন্ন উপায়ে তৈরি করা যায়, তবে সবচেয়ে সহজ পদ্ধতিগুলো হলো একটি সেট লিটারাল ডিক্লেয়ার করা, set ক্লাস কনস্ট্রাক্টর (set()) ব্যবহার করা, এবং একটি সেট কম্প্রিহেনশন ব্যবহার করা।
একটি set সরাসরি একটি সেট লিটারাল হিসেবে কার্লি {} বন্ধনী আর এলিমেন্টের মাঝে কমা দিয়ে লেখা যায়।
ডুপ্লিকেটগুলো চুপচাপ বাদ পড়ে:
>>> one_element = {'➕'}
{'➕'}
>>> multiple_elements = {'➕', '🔻', '🔹', '🔆'}
{'➕', '🔻', '🔹', '🔆'}
>>> multiple_duplicates = {'Hello!', 'Hello!', 'Hello!',
'¡Hola!','Привіт!', 'こんにちは!',
'¡Hola!','Привіт!', 'こんにちは!'}
{'こんにちは!', '¡Hola!', 'Hello!', 'Привіт!'}
সেট লিটারাল dict লিটারালের মতোই একই কার্লি ব্রেস ব্যবহার করে, তাই খালি set তৈরি করতে set() ব্যবহার করতে হয়।
set() (set ক্লাসের কনস্ট্রাক্টর) আর্গুমেন্ট হিসেবে পাঠানো যেকোনো iterable-এর সাথে ব্যবহার করা যায়।
iterable-এর এলিমেন্টগুলোর উপর এক এক করে ঘোরা হয় এবং প্রতিটি আলাদাভাবে set-এ যোগ করা হয়।
এলিমেন্টের ক্রম সংরক্ষিত হয় না এবং ডুপ্লিকেটগুলো চুপচাপ বাদ পড়ে:
# To create an empty set, the constructor must be used.
>>> no_elements = set()
set()
# The tuple is unpacked & each element is added.
# Duplicates are removed.
>>> elements_from_tuple = set(("Parrot", "Bird",
334782, "Bird", "Parrot"))
{334782, 'Bird', 'Parrot'}
# The list is unpacked & each element is added.
# Duplicates are removed.
>>> elements_from_list = set([2, 3, 2, 3, 3, 3, 5,
7, 11, 7, 11, 13, 13])
{2, 3, 5, 7, 11, 13}
lists আর dicts-এর মতো সেটও কম্প্রিহেনশন দিয়ে তৈরি করা যায়:
# First, a list with duplicates
>>> numbers = [1,2,3,4,5,6,6,5,4,8,9,9,9,2,3,12,18]
# This set comprehension squares the numbers divisible by 3
# Duplicates are removed.
>>> calculated = {item**2 for item in numbers if item % 3 == 0}
{9, 36, 81, 144, 324}
এর "আনপ্যাকিং" আচরণের কারণে স্ট্রিং দিয়ে set কনস্ট্রাক্টর ব্যবহার করলে হয়তো চমকে যাবেন:
# String elements (Unicode code points) are
# iterated through and added *individually*.
>>> elements_string = set("Timbuktu")
{'T', 'b', 'i', 'k', 'm', 't', 'u'}
# Unicode separators and positioning code points
# are also added *individually*.
>>> multiple_code_points_string = set('अभ्यास')
{'अ', 'भ', 'य', 'स', 'ा', '्'}
মনে রাখবেন: সেট ভিন্ন ডেটাটাইপ আর নেস্টেড ডেটাটাইপ ধারণ করতে পারে, তবে set-এর সব এলিমেন্টই hashable হতে হবে:
# Attempting to use a list for a set member throws a TypeError
>>> lists_as_elements = {['🌈','💦'],
['☁️','⭐️','🌍'],
['⛵️', '🚲', '🚀']}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
# Standard sets are mutable, so they cannot be hashed.
>>> sets_as_elements = {{'🌈','💦'},
{'☁️','⭐️','🌍'},
{'⛵️', '🚲', '🚀'}}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
তবে frozenset() টাইপ দিয়ে sets-এর একটি set তৈরি করা যায়:
# Frozensets don't have a literal form.
>>> set_1 = frozenset({'🌈','💦'})
>>> set_2 = frozenset({'☁️','⭐️','🌍'})
>>> set_3 = frozenset({'⛵️', '🚲', '🚀'})
>>> frozen_sets_as_elements = {set_1, set_2, set_3}
>>> frozen_sets_as_elements
{frozenset({'⛵️', '🚀', '🚲'}),
frozenset({'🌈', '💦'}),
frozenset({'☁️', '⭐️', '🌍'})}
<set>.add(<item>) আর <set>.remove(<item>) মেথড দিয়ে set-এ এলিমেন্ট যোগ বা অপসারণ করা যায়।
set-এ আইটেমটি না থাকলে .remove(<item>) মেথডটি একটি KeyError উত্থাপন করে:
>>> creatures = {'crow', 'duck', 'fish', 'monkey', 'elephant'}
>>> creatures.add('beaver')
>>> creatures.remove('duck')
>>> creatures
{'beaver', 'crow', 'elephant', 'fish', 'monkey'}
# Trying to remove an item that is not present raises a KeyError
>>> creatures.remove('bear')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'bear'
<set>.discard(<item>) set থেকে একটি আইটেম অপসারণ করে, কিন্তু আইটেমটি না থাকলে KeyError উত্থাপন করে না।<set>.clear() সেট থেকে সব আইটেম অপসারণ করে।<set>.pop() একটি যেকোনো আইটেম অপসারণ করে এবং রিটার্ন করে, আর set খালি থাকলে KeyError উত্থাপন করে।সেটের মেথডগুলো সাধারণত গাণিতিক সেট অপারেশন-এর অনুকরণ করে।
এই মেথডগুলোর বেশিরভাগের (সবগুলো নয়) একটি অপারেটর সমতুল্য রূপ আছে।
মেথড সাধারণত যেকোনো iterable আর্গুমেন্ট হিসেবে নেয়, আর অপারেটরের জন্য অপারেশনের দুই পাশই set বা frozenset হতে হয়।
একটি set-এর এলিমেন্টের সাথে অন্যটির এলিমেন্টের কোনো মিল আছে কি না পরীক্ষা করতে <set>.isdisjoint(<other_collection>) মেথড ব্যবহার করা হয়।
মেথডটি আর্গুমেন্ট হিসেবে যেকোনো iterable বা set গ্রহণ করে।
দুই সেটের কোনো এলিমেন্ট কমন না থাকলে এটি True রিটার্ন করে, আর এলিমেন্ট শেয়ার করা থাকলে False।
# Both mammals and additional_animals are lists.
>>> mammals = ['squirrel','dog','cat','cow', 'tiger', 'elephant']
>>> additional_animals = ['pangolin', 'panda', 'parrot',
'lemur', 'tiger', 'pangolin']
# Animals is a dict.
>>> animals = {'chicken': 'white',
'sparrow': 'grey',
'eagle': 'brown and white',
'albatross': 'grey and white',
'crow': 'black',
'elephant': 'grey',
'dog': 'rust',
'cow': 'black and white',
'tiger': 'orange and black',
'cat': 'grey',
'squirrel': 'black'}
# Birds is a set.
>>> birds = {'crow','sparrow','eagle','chicken', 'albatross'}
# Mammals and birds don't share any elements.
>>> birds.isdisjoint(mammals)
True
# There are also no shared elements between
# additional_animals and birds.
>>> birds.isdisjoint(additional_animals)
True
# Animals and mammals have shared elements.
# **Note** The first object needs to be a set or converted to a set
# since .isdisjoint() is a set method.
>>> set(animals).isdisjoint(mammals)
False
<set>-এর প্রতিটি এলিমেন্ট <other_collection>-এও আছে কি না পরীক্ষা করতে <set>.issubset(<other_collection>) ব্যবহার করা হয়।
অপারেটর রূপটি হলো <set> <= <other_set>:
# Set methods will take any iterable as an argument.
# All members of birds are also members of animals.
>>> birds.issubset(animals)
True
# All members of mammals also appear in animals.
# **Note** The first object needs to be a set or converted to a set
# since .issubset() is a set method.
>>> set(mammals).issubset(animals)
True
# Both objects need to be sets to use a set operator
>>> birds <= set(mammals)
False
# A set is always a loose subset of itself.
>>> set(additional_animals) <= set(additional_animals)
True
<set>.issuperset(<other_collection>) হলো .issubset()-এর বিপরীত।
<other_collection>-এর প্রতিটি এলিমেন্ট <set>-এও আছে কি না পরীক্ষা করতে এটি ব্যবহার করা হয়।
অপারেটর রূপটি হলো <set> >= <other_set>:
# All members of mammals also appear in animals.
# **Note** The first object needs to be a set or converted to a set
# since .issuperset() is a set method.
>>> set(animals).issuperset(mammals)
True
# All members of animals do not show up as members of birds.
>>> birds.issuperset(animals)
False
# Both objects need to be sets to use a set operator
>>> birds >= set(mammals)
False
# A set is always a loose superset of itself.
>>> set(animals) >= set(animals)
True
<set> < <other_set> আর <set> > <other_set> দিয়ে প্রপার সাবসেট পরীক্ষা করা হয়।
< অপারেটরের জন্য একটি set প্রপার সাবসেট হয় যদি (<set> <= <other_set>) এবং (<set> != <other_set>) হয়।
> অপারেটরের জন্য একটি set প্রপার সুপারসেট হয় যদি (<set> >= <other_set>) এবং (<set> != <other_set>) হয়।
এই অপারেটরগুলোর কোনো মেথড সমতুল্য রূপ নেই:
>>> animal_names = {'albatross','cat','chicken','cow','crow','dog',
'eagle','elephant','sparrow','squirrel','tiger'}
>>> animals_also = {'albatross','cat','chicken','cow','crow','dog',
'eagle','elephant','sparrow','squirrel','tiger'}
>>> mammals = {'squirrel','dog','cat','cow', 'tiger', 'elephant'}
>>> birds = {'crow','sparrow','eagle','chicken', 'albatross'}
>>> mammals < animal_names
True
>>> animal_names > birds
True
# A set is not a *proper subset* if set == other set.
>>> animals_also < animal_names
False
# A set is never a *proper subset* of itself
>>> animals_also < animals_also
False
<set>.union(*<other iterables>) <set> আর সব <other iterables>-এর এলিমেন্ট নিয়ে একটি নতুন set রিটার্ন করে।
এই মেথডের অপারেটর রূপটি হলো <set> | <other set 1> | <other set 2> | ... | <other set n>।
>>> perennials = {'Asparagus', 'Broccoli', 'Sweet Potato', 'Kale'}
>>> annuals = {'Corn', 'Zucchini', 'Sweet Peas', 'Summer Squash'}
>>> more_perennials = ['Radicchio', 'Rhubarb',
'Spinach', 'Watercress']
# Methods will take any iterable as an argument.
>>> perennials.union(more_perennials)
{'Asparagus','Broccoli','Kale','Radicchio','Rhubarb',
'Spinach','Sweet Potato','Watercress'}
# Operators require sets.
>>> set(more_perennials) | perennials
{'Asparagus',
'Broccoli',
'Kale',
'Radicchio',
'Rhubarb',
'Spinach',
'Sweet Potato',
'Watercress'}
<set>.difference(*<other iterables>) মূল <set>-এর যেসব এলিমেন্ট <others>-এ নেই, সেগুলো নিয়ে একটি নতুন set রিটার্ন করে।
এই মেথডের অপারেটর রূপটি হলো <set> - <other set 1> - <other set 2> - ... - <other set n>।
>>> berries_and_veggies = {'Asparagus',
'Broccoli',
'Watercress',
'Goji Berries',
'Goose Berries',
'Ramps',
'Walking Onions',
'Blackberries',
'Strawberries',
'Rhubarb',
'Kale',
'Artichokes',
'Currants'}
>>> veggies = ('Asparagus', 'Broccoli', 'Watercress', 'Ramps',
'Walking Onions', 'Rhubarb', 'Kale', 'Artichokes')
# Methods will take any iterable as an argument.
>>> berries = berries_and_veggies.difference(veggies)
{'Blackberries','Currants','Goji Berries',
'Goose Berries', 'Strawberries'}
# Operators require sets.
>>> berries_and_veggies - berries
{'Artichokes','Asparagus','Broccoli','Kale',
'Ramps','Rhubarb','Walking Onions','Watercress'}
<set>.intersection(*<other iterables>) মূল set আর সব <others>-এর কমন এলিমেন্ট নিয়ে একটি নতুন set রিটার্ন করে (অন্য কথায়, যে set-এ সবকিছু ইন্টারসেক্ট করে)।
এই মেথডের অপারেটর রূপটি হলো <set> & <other set> & <other set 2> & ... & <other set n>
>>> perennials = {'Annatto','Asafetida','Asparagus','Azalea',
'Winter Savory', 'Broccoli','Curry Leaf','Fennel',
'Kaffir Lime','Kale','Lavender','Mint','Oranges',
'Oregano', 'Tarragon', 'Wild Bergamot'}
>>> annuals = {'Corn', 'Zucchini', 'Sweet Peas', 'Marjoram',
'Summer Squash', 'Okra','Shallots', 'Basil',
'Cilantro', 'Cumin', 'Sunflower', 'Chervil',
'Summer Savory'}
>>> herbs = ['Annatto','Asafetida','Basil','Chervil','Cilantro',
'Curry Leaf','Fennel','Kaffir Lime','Lavender',
'Marjoram','Mint','Oregano','Summer Savory',
'Tarragon','Wild Bergamot','Wild Celery',
'Winter Savory']
# Methods will take any iterable as an argument.
>>> perennial_herbs = perennials.intersection(herbs)
{'Annatto', 'Asafetida', 'Curry Leaf', 'Fennel', 'Kaffir Lime',
'Lavender', 'Mint', 'Oregano', 'Wild Bergamot','Winter Savory'}
# Operators require both groups be sets.
>>> annuals & set(herbs)
{'Basil', 'Chervil', 'Marjoram', 'Cilantro'}
<set>.symmetric_difference(<other iterable>) এমন একটি নতুন set রিটার্ন করে যাতে <set> অথবা <other>-এ থাকা এলিমেন্ট থাকে, তবে দুটোতেই নয়।
এই মেথডের অপারেটর রূপটি হলো <set> ^ <other set>।
>>> plants_1 = {'🌲','🍈','🌵', '🥑','🌴', '🥭'}
>>> plants_2 = ('🌸','🌴', '🌺', '🌲', '🌻', '🌵')
# Methods will take any iterable as an argument.
>>> fruit_and_flowers = plants_1.symmetric_difference(plants_2)
>>> fruit_and_flowers
{'🌸', '🌺', '🍈', '🥑', '🥭','🌻' }
# Operators require both groups be sets.
>>> fruit_and_flowers ^ plants_1
{'🌲', '🌸', '🌴', '🌵','🌺', '🌻'}
>>> fruit_and_flowers ^ set(plants_2)
{'🥭', '🌴', '🌵', '🍈', '🌲', '🥑'}
দুইয়ের বেশি সেটের সিমেট্রিক ডিফারেন্সের ফলে যে set পাওয়া যায়, তাতে প্রতিটি set-এর নিজস্ব অনন্য এলিমেন্ট এবং সিরিজের দুইয়ের বেশি সেটের মধ্যে শেয়ার করা এলিমেন্ট দুটোই থাকে (বিস্তারিত symmetric difference নিয়ে উইকিপিডিয়া নিবন্ধে)।
সিরিজের প্রতিটি set-এর কেবল অনন্য আইটেম পেতে হলে, সব ২-সেট কম্বিনেশনের মধ্যে ইন্টারসেকশনগুলো আলাদা একটি ধাপে একত্র করে সরিয়ে ফেলতে হবে:
>>> one = {'black pepper','breadcrumbs','celeriac','chickpea flour',
'flour','lemon','parsley','salt','soy sauce',
'sunflower oil','water'}
>>> two = {'black pepper','cornstarch','garlic','ginger',
'lemon juice','lemon zest','salt','soy sauce','sugar',
'tofu','vegetable oil','vegetable stock','water'}
>>> three = {'black pepper','garlic','lemon juice','mixed herbs',
'nutritional yeast', 'olive oil','salt','silken tofu',
'smoked tofu','soy sauce','spaghetti','turmeric'}
>>> four = {'barley malt','bell pepper','cashews','flour',
'fresh basil','garlic','garlic powder', 'honey',
'mushrooms','nutritional yeast','olive oil','oregano',
'red onion', 'red pepper flakes','rosemary','salt',
'sugar','tomatoes','water','yeast'}
>>> intersections = (one & two | one & three | one & four |
two & three | two & four | three & four)
...
{'black pepper','flour','garlic','lemon juice','nutritional yeast',
'olive oil','salt','soy sauce', 'sugar','water'}
# The ^ operation will include some of the items in intersections,
# which means it is not a "clean" symmetric difference - there
# are overlapping members.
>>> (one ^ two ^ three ^ four) & intersections
{'black pepper', 'garlic', 'soy sauce', 'water'}
# Overlapping members need to be removed in a separate step
# when there are more than two sets that need symmetric difference.
>>> (one ^ two ^ three ^ four) - intersections
...
{'barley malt','bell pepper','breadcrumbs', 'cashews','celeriac',
'chickpea flour','cornstarch','fresh basil', 'garlic powder',
'ginger','honey','lemon','lemon zest','mixed herbs','mushrooms',
'oregano','parsley','red onion','red pepper flakes','rosemary',
'silken tofu','smoked tofu','spaghetti','sunflower oil', 'tofu',
'tomatoes','turmeric','vegetable oil','vegetable stock','yeast'}