BASIC Python (Beginner Level) 📂 Basic Python Programming · 11 of 15 254 min read

Python Sets — The Complete Guide to Methods

Master Python sets from the ground up — the O(1) membership superpower, all six mutation methods, and every set operation with visual Venn diagrams. Learn union, intersection, difference, and symmetric difference by picture and by code, plus subset/superset/disjoint relationships, frozensets, and five practical patterns from deduplication to permission checks. Includes benchmarks proving 3000× speedups over lists.

🌐
SectionSection第 01 节

The Story That Explains Sets 🎟️Sets समझाने वाली कहानी 🎟️一个解释集合的故事 🎟️

The Guest List at the Doorदरवाज़े पर मेहमानों की सूची门口的宾客名单
You are running the door at a private event. Someone walks up and says "I'm Alice, I'm on the list." Only two questions matter: Is Alice on the list — yes or no? You don't care what position she is on the list. You don't care if she is on it twice. You don't care who came before her.

Now imagine a printed 500-name list on paper. You would scan from top to bottom until you found her — slow and painful. Now imagine that list is a set. You look at Alice's name and know at once — without scanning — if she is in. That is not magic. It is a hash lookup, and it is the superpower of the Python set.

A set is a bag of unique, unordered things built for one job: answering "is this in there?" very fast.
आप किसी निजी कार्यक्रम के दरवाज़े पर खड़े हैं। कोई आकर कहता है "मैं Alice हूँ, मेरा नाम सूची में है।" सिर्फ़ दो सवाल मायने रखते हैं: क्या Alice सूची में है — हाँ या नहीं? आपको फ़र्क नहीं पड़ता कि वह सूची में किस नंबर पर है। आपको फ़र्क नहीं पड़ता कि उसका नाम दो बार लिखा है। आपको फ़र्क नहीं पड़ता कि उससे पहले कौन आया।

अब सोचिए कि काग़ज़ पर 500 नामों की छपी सूची है। आप ऊपर से नीचे तक पढ़ते जाएँगे जब तक वह न मिले — धीमा और थकाऊ। अब सोचिए कि वह सूची एक set है। आप Alice का नाम देखते हैं और तुरंत — बिना पूरी सूची पढ़े — जान जाते हैं कि वह अंदर है या नहीं। यह जादू नहीं है। यह hash lookup है, और यही Python set की ख़ास ताक़त है।

Set अनोखी (unique), बिना क्रम (unordered) चीज़ों का थैला है, जो एक ही काम के लिए बना है: "क्या यह इसमें है?" का जवाब बहुत तेज़ी से देना।
你在一个私人活动的门口检票。有人走过来说 "我是 Alice,名单上有我。" 只有两个问题重要:Alice 在名单上吗 — 是还是不是? 你不关心她排在第几个,不关心她的名字是否写了两次,也不关心谁比她先来。

现在想象一张印在纸上的 500 人名单。你得从上往下一行行找 — 又慢又累。再想象这份名单是一个 set。你看一眼 Alice 的名字,马上就知道她在不在 — 不用逐个扫描。这不是魔法,而是 hash 查找,也是 Python set 的超能力。

set 是一袋 不重复、无序 的东西,专为一件事而生:极快地回答 "这个在里面吗?"

A Python set is an unordered collection of unique, hashable items. It borrows union, intersection and difference from mathematics, and adds very fast membership tests. Every duplicate you give it is quietly dropped. Most membership questions are answered in one hop.

Python का set अनोखे, hashable items का बिना क्रम वाला संग्रह है। यह गणित से union, intersection और difference लेता है, और साथ में बहुत तेज़ membership जाँच देता है। आप जो भी duplicate देते हैं, वह चुपचाप हटा दिया जाता है। ज़्यादातर membership सवालों का जवाब एक ही छलाँग में मिल जाता है।

Python 的 set 是由不重复、可哈希元素组成的无序集合。它从数学中借来了并集、交集和差集,再加上非常快的成员检查。你放进去的每个重复项都会被悄悄丢掉。大多数成员检查一步就能得到答案。

💡
The Core Insightमूल बात核心要点

A set is a list without duplicates that has traded order for speed. You lose indexing (s[0] does not exist). You gain O(1) membership tests on average and maths operations that would take many lines with lists. It is the perfect tool for the questions "is X in the group?" and "what do these groups have in common?"

Set एक बिना duplicates वाली list है जिसने गति के बदले क्रम छोड़ दिया है। Indexing चली जाती है (s[0] नहीं होता)। बदले में मिलती है औसतन O(1) membership जाँच और ऐसे गणितीय operations जो lists के साथ कई lines लेते। यह "क्या X समूह में है?" और "इन समूहों में क्या साझा है?" जैसे सवालों का सबसे सही औज़ार है।

set 是一个 没有重复项的 list,它用顺序换来了速度。你失去了索引(没有 s[0]),得到的是 平均 O(1) 的成员检查,以及用 list 要写很多行才能完成的数学运算。它最适合回答 "X 在这个组里吗?" 和 "这些组有什么共同点?"

▶️
This Tutorial Has Seven Simulators and a Quizइस Tutorial में सात Simulators और एक Quiz है本教程有七个模拟器和一个小测验

Look for the interactive boxes: the Set Builder (Section 03), the Mutation Method Simulator (04), the Membership Race (05), the Venn Operation Lab (09), the Relationship Checker (10), the Frozenset Lab (11) and the Pattern Stepper (12). Type your own sets, press the buttons and watch each step. Results and errors match real Python.

Interactive डिब्बे खोजें: Set Builder (Section 03), Mutation Method Simulator (04), Membership Race (05), Venn Operation Lab (09), Relationship Checker (10), Frozenset Lab (11) और Pattern Stepper (12)। अपने sets लिखें, buttons दबाएँ और हर कदम देखें। Results और errors असली Python जैसे ही हैं।

请留意这些互动框:Set Builder(第 03 节)、Mutation Method Simulator(04)、Membership Race(05)、Venn Operation Lab(09)、Relationship Checker(10)、Frozenset Lab(11)和 Pattern Stepper(12)。输入你自己的 set,按下按钮,观察每一步。结果和错误都与真实的 Python 一致。


SectionSection第 02 节

The Three Laws of Every Set ⚖️हर Set के तीन नियम ⚖️每个 set 的三条定律 ⚖️

Before the syntax, learn the three properties that define every set. Every method, every operation and every edge case comes from these rules.

Syntax से पहले वे तीन गुण सीखें जो हर set को परिभाषित करते हैं। हर method, हर operation और हर ख़ास स्थिति इन्हीं नियमों से निकलती है।

在学语法之前,先记住定义每个 set 的三个性质。每个方法、每个运算和每种特殊情况都来自这些规则。

🎯
Law 1 — Uniqueनियम 1 — अनोखा定律 1 — 唯一
No duplicates, everकभी कोई duplicate नहीं永远没有重复
Adding an item that already exists does nothing — no error. {1, 1, 2, 2, 3} becomes {1, 2, 3} at once. This is why a set is the one-line answer to removing duplicates.
जो item पहले से है उसे जोड़ने पर कुछ नहीं होता — कोई error नहीं। {1, 1, 2, 2, 3} तुरंत {1, 2, 3} बन जाता है। इसीलिए duplicates हटाने का एक-line जवाब set है।
加入已经存在的元素什么也不做 — 也不报错。{1, 1, 2, 2, 3} 立刻变成 {1, 2, 3}。所以 set 是一行代码去重的答案。
🔀
Law 2 — Unorderedनियम 2 — बिना क्रम定律 2 — 无序
No index, no sliceन index, न slice没有索引,没有切片
Sets have no defined order. s[0] raises TypeError. The print order is not guaranteed. If order matters, you want a list — not a set.
Sets का कोई तय क्रम नहीं होता। s[0] TypeError देता है। Print का क्रम पक्का नहीं है। अगर क्रम ज़रूरी है, तो list चाहिए — set नहीं।
set 没有确定的顺序。s[0] 会抛出 TypeError。打印顺序没有保证。如果顺序重要,你需要 list — 而不是 set。
🔒
Law 3 — Hashable Onlyनियम 3 — सिर्फ़ Hashable定律 3 — 只能可哈希
Unchangeable itemsन बदलने वाले items不可变的元素
Only hashable objects fit inside a set: numbers, strings, tuples (of hashable items) and frozensets. Lists, dicts and other sets are not hashable and raise TypeError: unhashable type.
Set के अंदर सिर्फ़ hashable objects आते हैं: numbers, strings, tuples (जिनके items hashable हों) और frozensets। Lists, dicts और दूसरे sets hashable नहीं हैं और TypeError: unhashable type देते हैं।
只有 可哈希 的对象才能放进 set:数字、字符串、(元素都可哈希的)tuple 和 frozenset。list、dict 和其他 set 不可哈希,会抛出 TypeError: unhashable type。
Law 1 in Action — Duplicates Disappearनियम 1 काम में — Duplicates गायब定律 1 实战 — 重复项消失
A list with duplicates becomes a seta list: 9 items, in order, duplicates allowedएक list: 9 items, क्रम में, duplicates की इजाज़त一个 list:9 个元素,有顺序,允许重复3[0]1[1]4[2]1[3]✗ dup5[4]9[5]2[6]6[7]5[8]✗ dupset( )1234569set → {1, 2, 3, 4, 5, 6, 9}: 7 unique items, the two duplicates are goneset → {1, 2, 3, 4, 5, 6, 9}: 7 अनोखे items, दोनों duplicates गायबset → {1, 2, 3, 4, 5, 6, 9}:7 个不重复元素,两个重复项消失了

set([3, 1, 4, 1, 5, 9, 2, 6, 5]) keeps the first 1 and the first 5 and drops the copies. Small ints print in number order because their hash is the number itself — that is a side effect, not a rule.

set([3, 1, 4, 1, 5, 9, 2, 6, 5]) पहला 1 और पहला 5 रखता है और copies हटा देता है। छोटे ints संख्या के क्रम में print होते हैं क्योंकि उनका hash वही संख्या है — यह संयोग है, नियम नहीं।

set([3, 1, 4, 1, 5, 9, 2, 6, 5]) 保留第一个 1 和第一个 5,丢掉副本。小整数按大小顺序打印,是因为它们的 hash 就是数字本身 — 这只是副作用,不是规则。


SectionSection第 03 节

Creating a Set — Four Ways 🛠️Set बनाना — चार तरीके 🛠️创建 set — 四种方法 🛠️

# 1) Literal — the cleanest and most common
colours = {"red", "green", "blue"}

# 2) From an iterable using the set() constructor
letters = set("hello")          # 'l' appears twice, kept once
nums    = set([1, 2, 2, 3, 3])   # {1, 2, 3}

# 3) Set comprehension — filter + transform in one step
squares = {n ** 2 for n in range(6)}

# 4) Empty set — the ONE case where the {} literal fails
empty = set()      # CORRECT — empty set
oops  = {}         # WRONG — this is an empty DICT, not a set!

print(colours)     # string order changes from run to run
print(letters)
print(nums)
print(squares)
print(empty)
print(type(oops).__name__)  # dict, not set
OUTPUT
{'red', 'green', 'blue'} {'l', 'o', 'e', 'h'} {1, 2, 3} {0, 1, 4, 9, 16, 25} set() dict
💡
Your Output May Look Differentआपका Output अलग दिख सकता है你的输出可能不同

The order of the strings in {'red', 'green', 'blue'} and {'e', 'h', 'l', 'o'} changes from run to run, because string hashes are randomized each time Python starts. The numbers come out sorted here only because a small int is its own hash.

{'red', 'green', 'blue'} और {'e', 'h', 'l', 'o'} में strings का क्रम हर run में बदलता है, क्योंकि Python हर बार शुरू होने पर string hashes को random बनाता है। यहाँ numbers क्रम में इसलिए दिखते हैं क्योंकि छोटे int का hash वही संख्या है।

{'red', 'green', 'blue'} 和 {'e', 'h', 'l', 'o'} 中字符串的顺序每次运行都会变,因为 Python 每次启动时字符串 hash 都会 随机化。这里的数字看起来是排好序的,只是因为小整数的 hash 就是它本身。

⚠️
The Empty-Set Trap Every Beginner Hitsखाली-Set का जाल जिसमें हर नया सीखने वाला फँसता है每个初学者都会踩的空 set 陷阱

In Python, {} is always an empty dict — never a set. To create an empty set you must write set(). Dicts got the curly braces first, long before set literals arrived. The bug is silent until you call .add() and get AttributeError: 'dict' object has no attribute 'add'.

Python में {} हमेशा खाली dict होता है — कभी set नहीं। खाली set बनाने के लिए set() लिखना ज़रूरी है। Curly braces पहले dicts को मिले थे, set literals बहुत बाद में आए। यह bug तब तक चुप रहता है जब तक आप .add() न चलाएँ और AttributeError: 'dict' object has no attribute 'add' न मिले।

在 Python 中,{} 永远 是空 dict — 绝不是 set。创建空 set 必须 写 set()。花括号先给了 dict,set 字面量很久以后才出现。这个 bug 不会报错,直到你调用 .add() 得到 AttributeError: 'dict' object has no attribute 'add'。

One Surprise: 1, 1.0 and True Are the Same Itemएक हैरानी: 1, 1.0 और True एक ही Item हैं一个意外:1、1.0 和 True 是同一个元素

A set decides "duplicate" with two checks: same hash and ==. Numbers that are equal also have equal hashes, so they collapse into one item even if their types differ.

Set "duplicate" का फ़ैसला दो जाँचों से करता है: hash बराबर और ==। बराबर numbers के hash भी बराबर होते हैं, इसलिए अलग types होने पर भी वे एक ही item बन जाते हैं।

set 用两个检查来判断 "重复":hash 相同 和 ==。相等的数字 hash 也相等,所以即使类型不同,它们也会合并成一个元素。

# 1, 1.0 and True are equal AND have the same hash
print(1 == 1.0 == True)
print(hash(1), hash(1.0), hash(True))

# So a set keeps only the first one it sees
print({1, 1.0, True})
print({True, 1, 1.0})
print(len({0, 0.0, False, "0"}))   # "0" is text, so it stays
OUTPUT
True 1 1 1 {1} {True} 2
⚠️
The First One Winsजो पहले आया, वही रहता है先到的那个留下

The set keeps the first value it saw: {1, 1.0, True} prints {1}, but {True, 1, 1.0} prints {True}. Avoid mixing bool with numbers in one set.

Set पहली देखी गई value रखता है: {1, 1.0, True} {1} print करता है, पर {True, 1, 1.0} {True}। एक set में bool और numbers न मिलाएँ।

set 保留它 第一个 见到的值:{1, 1.0, True} 打印 {1},而 {True, 1, 1.0} 打印 {True}。不要在一个 set 里混用 bool 和数字。

Try It — Set Builder (Inside the Hash Table)करके देखें — Set Builder (Hash Table के अंदर)动手试试 — Set Builder(哈希表内部)

Why does set([3, 1, 4, 1, 5]) print in its own order? Build a set one item at a time and watch. Each item is hashed, the hash picks a slot, and duplicates are caught when they land on an equal item. Printing walks the slots in order — that is the "unordered" order.

set([3, 1, 4, 1, 5]) अपने ही क्रम में क्यों print होता है? एक-एक item डालकर set बनाइए और देखिए। हर item का hash बनता है, hash एक slot चुनता है, और बराबर item पर पहुँचते ही duplicate पकड़ा जाता है। Print slots को क्रम से पढ़ता है — यही "बिना क्रम" वाला क्रम है।

为什么 set([3, 1, 4, 1, 5]) 按它自己的顺序打印?一个一个地加入元素来建 set 并观察。每个元素先计算 hash,hash 选出一个 slot,落到相等元素上时就发现了重复。打印时按 slot 顺序走 — 这就是 "无序" 的顺序。

🏗️ Set Builderhash → slot → store. Duplicates are skipped.hash → slot → store. Duplicates छोड़ दिए जाते हैं।hash → slot → 存储。重复项被跳过。
Try:आज़माएँ:试试:
items to addजोड़ने वाले items要加入的元素
hash table slotshash table के slots哈希表 slot
💡
About String OrderString के क्रम के बारे में关于字符串的顺序

Numbers use Python's real hash, so the order you see matches real Python. String hashes are randomized each time Python starts, so real Python prints a set of strings in a different order on each run. The simulator uses a fixed stand-in hash for strings — it shows one possible order.

Numbers Python का असली hash इस्तेमाल करते हैं, इसलिए दिखने वाला क्रम असली Python जैसा है। String hashes हर बार Python शुरू होने पर random होते हैं, इसलिए असली Python strings के set को हर run में अलग क्रम में print करता है। Simulator strings के लिए एक तय नकली hash इस्तेमाल करता है — यह एक संभावित क्रम दिखाता है।

数字使用 Python 真实的 hash,所以你看到的顺序和真实 Python 一样。字符串的 hash 每次 Python 启动时都会 随机化,所以真实 Python 每次运行打印字符串 set 的顺序都不同。模拟器对字符串用一个固定的替代 hash — 它只展示 一种 可能的顺序。


SectionSection第 04 节

Adding & Removing — The Mutation Methods ✏️जोड़ना और हटाना — बदलने वाले Methods ✏️添加与删除 — 修改方法 ✏️

🧠 Six Methods That Change the SetSet को बदलने वाले छह Methods改变 set 的六个方法
add
Adds one item. Silent if it already exists — no error, no duplicate. एक item जोड़ता है। पहले से हो तो चुप रहता है — न error, न duplicate। 加入一个元素。已存在时不做任何事 — 不报错,也不重复。
update
Adds many items from any iterable. Also silent about duplicates. किसी भी iterable से कई items जोड़ता है। Duplicates पर भी चुप। 从任意可迭代对象加入多个元素。对重复项同样不报错。
remove
Removes one item. Raises KeyError if it is not there. एक item हटाता है। न हो तो KeyError देता है। 删除一个元素。不存在时抛出 KeyError。
discard
Removes one item. Silent if it is not there — no error. एक item हटाता है। न हो तो चुप — कोई error नहीं। 删除一个元素。不存在时什么也不做 — 不报错。
pop
Removes and returns an arbitrary item. Raises KeyError if the set is empty. कोई भी एक item हटाकर लौटाता है। Set खाली हो तो KeyError। 删除并返回任意一个元素。set 为空时抛出 KeyError。
clear
Removes everything. The set becomes empty. सब कुछ हटाता है। Set खाली हो जाता है। 删除所有元素。set 变为空。
fruits = {"apple", "banana"}

fruits.add("cherry")          # adds one item
fruits.add("apple")           # no change — silent duplicate

fruits.update(["kiwi", "mango"]) # adds both from a list
fruits.update("AB")              # adds 'A' AND 'B' — strings are iterable!
print(len(fruits))

fruits.discard("kiwi")          # removes safely, silent if absent
fruits.discard("grape")         # NOT there — but no error

try:
    fruits.remove("grape")      # NOT there — raises KeyError
except KeyError as e:
    print(f"KeyError: {e}")

random_fruit = fruits.pop()      # removes one arbitrary item
print(f"Popped: {random_fruit}")

fruits.clear()                   # now empty
print(f"After clear: {fruits}")
OUTPUT
7 KeyError: 'grape' Popped: banana After clear: set()
💡
Why "Popped: A"?"Popped: A" क्यों?为什么是 "Popped: A"?

pop() takes whatever sits in the first used slot it finds. With string items that depends on the random string hashes, so you may see apple, mango or another item on your machine. Never rely on which item pop() returns.

pop() पहले भरे हुए slot में जो मिले, वही ले लेता है। String items के साथ यह random string hashes पर निर्भर है, इसलिए आपकी मशीन पर apple, mango या कोई और item आ सकता है। pop() कौन-सा item लौटाएगा, इस पर कभी भरोसा न करें।

pop() 取它找到的第一个已用 slot 里的元素。对字符串元素来说,这取决于随机的字符串 hash,所以你的电脑上可能是 apple、mango 或别的元素。永远不要依赖 pop() 返回哪一个。

🔑
remove vs discard — Pick On Purposeremove बनाम discard — सोच-समझकर चुनेंremove 还是 discard — 有意识地选择

Use remove when the item should be there and its absence is a bug — you want the crash. Use discard when absence is fine — "delete if present, otherwise do nothing." Choosing one is choosing between strict and forgiving code.

remove तब इस्तेमाल करें जब item होना ही चाहिए और उसका न होना bug है — आप crash चाहते हैं। discard तब इस्तेमाल करें जब न होना ठीक है — "हो तो हटाओ, नहीं तो कुछ मत करो।" एक चुनना, सख़्त और नरम code के बीच चुनना है।

当元素 应该存在、缺失就是 bug 时,用 remove — 你希望程序报错。当缺失没关系时,用 discard — "有就删,没有就算了"。选哪一个,就是在严格的代码和宽容的代码之间做选择。

Try It — Mutation Method Simulatorकरके देखें — Mutation Method Simulator动手试试 — 修改方法模拟器

Run each method on fruits and compare before and after. Green items were added, red ones removed. Try the traps: add("apple") twice, update("AB") and remove("grape").

fruits पर हर method चलाएँ और पहले व बाद में की तुलना करें। हरे items जुड़े, लाल हटे। जाल आज़माएँ: add("apple") दो बार, update("AB") और remove("grape")।

在 fruits 上运行每个方法,对比 之前 和 之后。绿色的是加入的,红色的是删除的。试试这些陷阱:两次 add("apple")、update("AB") 和 remove("grape")。

🔧 Mutation Method SimulatorMutation Method Simulator修改方法模拟器Changes stay between runs, like real Python.असली Python की तरह बदलाव runs के बीच बने रहते हैं।和真实 Python 一样,修改会在多次运行之间保留。
Try:आज़माएँ:试试:
beforeपहले之前
afterबाद में之后

SectionSection第 05 节

Membership Testing — The Superpower ⚡Membership जाँच — असली ताक़त ⚡成员检查 — 超能力 ⚡

This is why sets exist. Checking whether an item is inside a collection is one of the most common jobs in programming, and sets do it in constant time on average — the size of the set does not matter.

Sets इसी काम के लिए बने हैं। कोई item संग्रह में है या नहीं, यह जाँचना programming का सबसे आम काम है, और sets इसे औसतन constant time में करते हैं — set का आकार मायने नहीं रखता।

这就是 set 存在的原因。检查某个元素是否在集合中,是编程中最常见的工作之一,而 set 能在 平均常数时间 内完成 — 与 set 的大小无关。

allowed_users = {"alice", "bob", "charlie", "diana"}

# The 'in' operator — O(1) on average, whatever the set size
print("alice" in allowed_users)     # True
print("eve" not in allowed_users)   # True

# Same test on a 1-million-item set — still about one step
big_set = set(range(1_000_000))
print(999_999 in big_set)          # True — instant
OUTPUT
True True True
❌ List Membership — O(n)List Membership — O(n)list 成员检查 — O(n)
Sizeआकार大小Measured timeनापा गया समय实测时间
1,000≈ 5 µs
100,000≈ 0.5 ms
1,000,000≈ 7.5 ms
Grows with n — painful at scalen के साथ बढ़ता है — बड़े आकार पर भारी随 n 增长 — 规模大时很慢
✅ Set Membership — O(1) on averageSet Membership — औसतन O(1)set 成员检查 — 平均 O(1)
Sizeआकार大小Measured timeनापा गया समय实测时间
1,000≈ 40 ns
100,000≈ 40 ns
1,000,000≈ 45 ns
Flat — same speed at every sizeसपाट — हर आकार पर एक जैसी गति平坦 — 任何大小速度都一样

Worst case for the list (the last item), measured on Python 3.13.16. Your numbers will differ, but the shape will not: 1,000× more items means about 1,000× more time for the list, and no change for the set.

List का सबसे बुरा मामला (आख़िरी item), Python 3.13.16 पर नापा गया। आपके numbers अलग होंगे, पर रुझान नहीं: 1,000 गुना ज़्यादा items यानी list के लिए लगभग 1,000 गुना ज़्यादा समय, और set के लिए कोई बदलाव नहीं।

list 的最坏情况(最后一个元素),在 Python 3.13.16 上实测。你的数字会不同,但规律不变:元素多 1,000 倍,list 大约慢 1,000 倍,而 set 不变。

Try It — Membership Race: List vs Setकरके देखें — Membership दौड़: List बनाम Set动手试试 — 成员检查赛跑:list 对 set

Both hold the same numbers. Press Race and watch: the list looks at items one by one; the set computes one hash and jumps to a slot. Try a missing value to see the list's worst case.

दोनों में वही numbers हैं। Race दबाएँ और देखें: list एक-एक item देखती है; set एक hash निकालकर slot पर छलाँग लगाता है। List का सबसे बुरा मामला देखने के लिए कोई ग़ायब value आज़माएँ।

两者存着相同的数字。按 Race 观察:list 逐个查看元素;set 计算一次 hash 就跳到一个 slot。试一个不存在的值,看看 list 的最坏情况。

🏎️ Membership RaceMembership दौड़成员检查赛跑x in list vs x in set
Try:आज़माएँ:试试:
💡
Why "On Average"?"औसतन" क्यों?为什么说 "平均"?

O(1) is the average case. If many items land on the same slots (collisions), Python must check a few more slots. CPython keeps the table at most 3/5 full and uses well-spread hashes, so in practice a lookup almost always takes one or two probes.

O(1) औसत मामला है। अगर बहुत से items एक ही slots पर आएँ (टकराव), तो Python को कुछ और slots देखने पड़ते हैं। CPython table को ज़्यादा से ज़्यादा 3/5 भरा रखता है और अच्छे फैले हुए hashes इस्तेमाल करता है, इसलिए असल में lookup लगभग हमेशा एक या दो probes में हो जाता है।

O(1) 是 平均 情况。如果很多元素落到同样的 slot(冲突),Python 就要多查几个 slot。CPython 让表最多 3/5 满,并使用分布良好的 hash,所以实际上一次查找几乎总是只需一两次探测。


SectionSection第 06 节

Set Operations — Visual Reference 🔵🔴Set Operations — चित्रों में 🔵🔴集合运算 — 图示 🔵🔴

This is where sets shine. Four jobs that would need nested loops with lists become a single symbol. The next four sections use the same two sets, a = {1, 2, 3, 4} and b = {3, 4, 5, 6}, so you can compare the results. In each Venn diagram the coloured region is the result.

यहीं sets चमकते हैं। चार काम जिनके लिए lists में nested loops लगते, एक अकेला चिह्न बन जाते हैं। अगले चार sections में वही दो sets हैं, a = {1, 2, 3, 4} और b = {3, 4, 5, 6}, ताकि आप results की तुलना कर सकें। हर Venn चित्र में रंगीन हिस्सा ही result है।

这正是 set 的强项。用 list 需要嵌套循环的四件事,变成了 一个符号。接下来四节都用同样的两个 set:a = {1, 2, 3, 4} 和 b = {3, 4, 5, 6},方便你比较结果。每个韦恩图中,着色部分就是结果。

OperatorOperator运算符MethodMethod方法Meaningअर्थ含义Result for a, ba, b के लिए resulta、b 的结果
a | ba.union(b)in a OR ba या b में在 a 或 b 中{1, 2, 3, 4, 5, 6}
a & ba.intersection(b)in a AND ba और b दोनों में同时在 a 和 b 中{3, 4}
a - ba.difference(b)in a, NOT in ba में, b में नहीं在 a 中,不在 b 中{1, 2}
a ^ ba.symmetric_difference(b)in one, NOT bothकिसी एक में, दोनों में नहीं只在其中一个中{1, 2, 5, 6}

Union — A | B — Everything from BothUnion — A | B — दोनों से सब कुछ并集 — A | B — 两边的全部

Set Operation: Union (A ∪ B)Set Operation: Union (A ∪ B)集合运算:并集 (A ∪ B)
unionAB123456A | B → everything in A OR B (or both)A | B → A या B (या दोनों) में सब कुछA | B → 在 A 或 B(或两者)中的全部

The whole shaded shape is the union — every item from either set, duplicates collapsed.

पूरा रंगीन आकार union है — किसी भी set का हर item, duplicates मिलाकर एक।

整个着色区域就是并集 — 两个 set 的所有元素,重复的合并为一个。

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

# Operator form — clean and Pythonic
print(a | b)              # {1, 2, 3, 4, 5, 6}

# Method form — accepts ANY iterable, not just sets
print(a.union(b, [7, 8])) # {1, 2, 3, 4, 5, 6, 7, 8}

# In-place version — changes a
a |= b
print(a)                  # {1, 2, 3, 4, 5, 6}
OUTPUT
{1, 2, 3, 4, 5, 6} {1, 2, 3, 4, 5, 6, 7, 8} {1, 2, 3, 4, 5, 6}

SectionSection第 07 节

Intersection — A & B — Common Items Only 🤝Intersection — A & B — सिर्फ़ साझा Items 🤝交集 — A & B — 只要共同元素 🤝

Set Operation: Intersection (A ∩ B)Set Operation: Intersection (A ∩ B)集合运算:交集 (A ∩ B)
interAB123456A & B → only items present in BOTH setsA & B → सिर्फ़ वे items जो दोनों sets में हैंA & B → 只要两个 set 都有的元素

Only the overlap is shaded. This is the mathematical intersection.

सिर्फ़ बीच का साझा हिस्सा रंगीन है। यही गणित का intersection है।

只有重叠部分被着色。这就是数学上的交集。

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

# Operator form
print(a & b)                       # {3, 4}

# Method form
print(a.intersection(b))            # {3, 4}

# Real use: users who are BOTH admins AND active
admins = {"alice", "bob", "charlie"}
active = {"bob", "charlie", "diana", "eve"}
active_admins = admins & active
print(f"Active admins: {sorted(active_admins)}")
OUTPUT
{3, 4} {3, 4} Active admins: ['bob', 'charlie']
💡
Why sorted() in the f-string?f-string में sorted() क्यों?为什么 f-string 里用 sorted()?

A set of strings prints in a different order on each run. Wrapping it in sorted() gives a list in a fixed order, so the output above is the same every time you run it. Use this trick whenever you show a set to a user.

Strings का set हर run में अलग क्रम में print होता है। sorted() से लपेटने पर तय क्रम वाली list मिलती है, इसलिए ऊपर का output हर बार एक जैसा आता है। जब भी user को set दिखाएँ, यह तरीका इस्तेमाल करें।

字符串 set 每次运行的打印顺序都不同。用 sorted() 包起来会得到顺序固定的 list,所以上面的输出每次都一样。给用户展示 set 时,都可以用这个技巧。


SectionSection第 08 节

Difference — A - B — In A but Not in B ➖Difference — A - B — A में, पर B में नहीं ➖差集 — A - B — 在 A 中但不在 B 中 ➖

Set Operation: Difference (A − B)Set Operation: Difference (A − B)集合运算:差集 (A − B)
diffAB123456A - B → in A, but NOT in BA - B → A में, पर B में नहींA - B → 在 A 中,但不在 B 中

The crescent on the left is shaded — items of A that B does not have.

बाईं ओर का अर्धचंद्र रंगीन है — A के वे items जो B में नहीं हैं।

左边的月牙形被着色 — A 中 B 没有的元素。

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a - b)                       # {1, 2}  — in a, not in b
print(b - a)                       # {5, 6}  — in b, not in a
print(a.difference(b))              # {1, 2}

# Real use: which requested features are NOT yet built?
requested = {"dark_mode", "exports", "api_v2", "webhooks"}
built     = {"dark_mode", "exports"}
pending   = requested - built
print(f"Still to build: {sorted(pending)}")
OUTPUT
{1, 2} {5, 6} {1, 2} Still to build: ['api_v2', 'webhooks']
⚠️
Difference Is NOT SymmetricDifference सममित (Symmetric) नहीं है差集不对称

Unlike union and intersection, a - b and b - a give different results. Order matters here. Read it as "start with the left set, then take away the right set."

Union और intersection के उलट, a - b और b - a अलग results देते हैं। यहाँ क्रम मायने रखता है। इसे ऐसे पढ़ें: "बाएँ set से शुरू करो, फिर दाएँ set को घटाओ।"

与并集和交集不同,a - b 和 b - a 的结果不同。这里顺序很重要。读作 "从左边的 set 开始,再减去右边的 set"。


SectionSection第 09 节

Symmetric Difference — A ^ B — In One but Not Both 🔀Symmetric Difference — A ^ B — एक में, दोनों में नहीं 🔀对称差集 — A ^ B — 只在其中一个中 🔀

Set Operation: Symmetric Difference (A △ B)Set Operation: Symmetric Difference (A △ B)集合运算:对称差集 (A △ B)
symAB123456A ^ B → in A OR B, but NOT bothA ^ B → A या B में, पर दोनों में नहींA ^ B → 在 A 或 B 中,但不同时在两者中

Both crescents are shaded and the middle is left out. This is (A ∪ B) − (A ∩ B).

दोनों अर्धचंद्र रंगीन हैं और बीच का हिस्सा छूटा है। यह (A ∪ B) − (A ∩ B) है।

两个月牙都被着色,中间被排除。这就是 (A ∪ B) − (A ∩ B)。

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a ^ b)                              # {1, 2, 5, 6}
print(a.symmetric_difference(b))          # {1, 2, 5, 6}
print((a | b) - (a & b))                  # same thing, the long way

# Real use: what changed between two snapshots?
yesterday = {"file_a.csv", "file_b.csv", "file_c.csv"}
today     = {"file_b.csv", "file_c.csv", "file_d.csv"}
changes = yesterday ^ today
print(f"Changed files: {sorted(changes)}")   # deleted + new
OUTPUT
{1, 2, 5, 6} {1, 2, 5, 6} {1, 2, 5, 6} Changed files: ['file_a.csv', 'file_d.csv']

Operators vs Methods, and the In-Place VersionsOperators बनाम Methods, और In-Place रूप运算符与方法,以及原地修改版本

Each operation comes in three forms. The operator (|) needs sets on both sides. The method (.union()) accepts any iterable. The in-place form (|=, .update()) changes the set itself instead of building a new one.

हर operation के तीन रूप हैं। Operator (|) को दोनों तरफ़ sets चाहिए। Method (.union()) कोई भी iterable लेता है। In-place रूप (|=, .update()) नया set बनाने की जगह उसी set को बदल देता है।

每种运算都有三种形式。运算符(|)要求两边都是 set。方法(.union())接受任何可迭代对象。原地形式(|=、.update())直接修改这个 set,而不是创建新的。

a = {1, 2, 3}

# Operators need a set on BOTH sides...
try:
    print(a | [3, 4])
except TypeError as e:
    print("TypeError:", e)

# ...but the methods accept any iterable
print(a.union([3, 4]))             # list
print(a.intersection([2, 3, 9]))  # list
print(a.intersection("123"))       # set() — "1" is text, not the number 1
print(a.difference(range(2)))      # range

# In-place versions change the set itself and return None
s = {1, 2, 3, 4}
s &= {2, 3, 9}                      # same as s.intersection_update(...)
print(s)
s -= {3}                            # same as s.difference_update(...)
print(s)
s ^= {2, 7}                         # same as s.symmetric_difference_update(...)
print(s)
print(s.update([8]))                # in-place methods return None
OUTPUT
TypeError: unsupported operand type(s) for |: 'set' and 'list' {1, 2, 3, 4} {2, 3} set() {2, 3} {2, 3} {2} {7} None
⚠️
Two Traps in That Outputउस Output में दो जाल这段输出里的两个陷阱

a.intersection("123") gives set(), because the string gives the characters '1', '2', '3', and text never equals a number. And in-place methods return None, so s = s.update(x) throws your set away.

a.intersection("123") set() देता है, क्योंकि string से अक्षर '1', '2', '3' मिलते हैं, और text कभी number के बराबर नहीं होता। और in-place methods None लौटाते हैं, इसलिए s = s.update(x) आपका set फेंक देता है।

a.intersection("123") 得到 set(),因为字符串给出的是 字符 '1'、'2'、'3',而文本永远不等于数字。另外,原地方法返回 None,所以 s = s.update(x) 会把你的 set 丢掉。

Try It — Venn Operation Lab (All Four Operations)करके देखें — Venn Operation Lab (चारों Operations)动手试试 — 韦恩运算实验室(全部四种运算)

Type two sets and pick an operation. The diagram sorts every item into its region, then the lab walks through the items the same way CPython does — for example, & loops over the smaller set. The green regions are the result.

दो sets लिखें और एक operation चुनें। चित्र हर item को उसके हिस्से में रखता है, फिर lab items पर वैसे ही चलता है जैसे CPython — उदाहरण के लिए, & छोटे set पर loop चलाता है। हरे हिस्से result हैं।

输入两个 set 并选择一种运算。图会把每个元素放进它的区域,然后实验室按 CPython 的方式逐个处理元素 — 例如 & 遍历 较小的 set。绿色区域就是结果。

⚪ Venn Operation LabUnion, intersection, difference, symmetric difference — step by step.Union, intersection, difference, symmetric difference — कदम-दर-कदम।并集、交集、差集、对称差集 — 一步一步。
Try:आज़माएँ:试试:

SectionSection第 10 节

Set Relationships — Subset, Superset, Disjoint 🧩Set के रिश्ते — Subset, Superset, Disjoint 🧩集合关系 — 子集、超集、不相交 🧩

Sets can also be compared as wholes. Is one set completely inside another? Do two sets share nothing at all? Each question has a one-call answer.

Sets की पूरी तरह तुलना भी हो सकती है। क्या एक set पूरी तरह दूसरे के अंदर है? क्या दो sets में कुछ भी साझा नहीं? हर सवाल का जवाब एक call में मिलता है।

set 也可以作为整体来 比较。一个 set 是否完全在另一个里面?两个 set 是否完全没有共同元素?每个问题都只需一次调用。

Set Relationships — Three PatternsSet के रिश्ते — तीन रूप集合关系 — 三种情况
subset, overlap, disjointABABABB ⊆ A (subset)B ⊆ A (subset)B ⊆ A(子集)A ∩ B ≠ ∅ (overlap)A ∩ B ≠ ∅ (आंशिक मेल)A ∩ B ≠ ∅(有重叠)A ∩ B = ∅ (disjoint)A ∩ B = ∅ (disjoint)A ∩ B = ∅(不相交)

Left: every item of B is also in A. Middle: they share some items. Right: they share nothing at all.

बाएँ: B का हर item A में भी है। बीच: कुछ items साझा हैं। दाएँ: कुछ भी साझा नहीं।

左:B 的每个元素都在 A 中。中:有部分共同元素。右:完全没有共同元素。

a = {1, 2, 3, 4, 5}
b = {2, 3}
c = {7, 8, 9}

# Subset — is every item of b also in a?
print(b.issubset(a))          # True
print(b <= a)                  # True  (operator form)
print(b < a)                   # True  (STRICT subset — b != a)
print(a < a, a <= a)           # False True — never a strict subset of itself

# Superset — the mirror question
print(a.issuperset(b))        # True
print(a >= b)                  # True

# Disjoint — do they share ZERO items?
print(a.isdisjoint(c))        # True — nothing in common
print(a.isdisjoint(b))        # False — they overlap
OUTPUT
True True True False True True True True False
🔑
Proper vs Non-Proper SubsetsProper बनाम Non-Proper Subsets真子集与非真子集

a <= b means "a is a subset of b, and may be equal." a < b means "a is a strict subset — everything in a is in b, and b has at least one more item." A set is always a non-strict subset of itself, but never a strict one: a < a is False.

a <= b का अर्थ है "a, b का subset है, और बराबर भी हो सकता है।" a < b का अर्थ है "a एक strict subset है — a का सब कुछ b में है, और b में कम से कम एक item ज़्यादा है।" कोई set हमेशा अपना non-strict subset है, पर कभी strict नहीं: a < a False है।

a <= b 的意思是 "a 是 b 的子集,可以相等"。a < b 的意思是 "a 是 真子集 — a 的所有元素都在 b 中,并且 b 至少多一个元素"。set 永远是自己的非真子集,但绝不是真子集:a < a 是 False。

Try It — Relationship Checkerकरके देखें — Relationship Checker动手试试 — 关系检查器

Pick a comparison and see how Python answers it. Notice the shortcuts: a size check first, and the loop stops at the first item that fails.

कोई तुलना चुनें और देखें कि Python उसका जवाब कैसे देता है। Shortcuts पर ध्यान दें: पहले आकार की जाँच, और पहला असफल item मिलते ही loop रुक जाता है।

选择一种比较,看 Python 怎样回答。注意其中的捷径:先做 大小检查,遇到第一个不满足的元素循环就停止。

🔗 Relationship CheckerSubset, superset, equal, disjoint — with every check shown.Subset, superset, बराबर, disjoint — हर जाँच के साथ।子集、超集、相等、不相交 — 每一步检查都显示。
Try:आज़माएँ:试试:

SectionSection第 11 节

Frozenset — The Unchangeable Cousin 🧊Frozenset — न बदलने वाला भाई 🧊Frozenset — 不可变的兄弟 🧊

A normal set can change — you can add and remove items. Sometimes you need a hashable, unchangeable version: an item inside another set, a dictionary key, or a value that must never change. That is frozenset.

साधारण set बदल सकता है — आप items जोड़ और हटा सकते हैं। कभी-कभी आपको hashable, न बदलने वाला रूप चाहिए: किसी दूसरे set के अंदर item, dictionary key, या ऐसी value जो कभी न बदले। वही frozenset है।

普通 set 可以修改 — 你可以添加和删除元素。有时你需要一个 可哈希、不可变 的版本:作为另一个 set 的元素、作为字典的 key,或作为永远不变的值。这就是 frozenset。

# Create a frozenset from any iterable
permissions = frozenset(["read", "write", "delete"])

# All non-changing operations still work
print("read" in permissions)               # True
bigger = permissions | {"admin"}           # returns a NEW frozenset
print(type(bigger).__name__, len(bigger))

# But changing it is forbidden
try:
    permissions.add("admin")
except AttributeError as e:
    print(f"Blocked: {e}")

# Because it's hashable, a frozenset can be:
# 1) an item of another set
role_bundles = {
    frozenset({"read"}),
    frozenset({"read", "write"}),
    frozenset({"read", "write", "admin"})
}
print(len(role_bundles))                    # 3

# 2) a dictionary key
cache = {
    frozenset(["a", "b"]): "result_ab",
    frozenset(["c", "d"]): "result_cd",
}
print(cache[frozenset(["b", "a"])])       # order doesn't matter
OUTPUT
True frozenset 4 Blocked: 'frozenset' object has no attribute 'add' 3 result_ab
💡
What Did permissions | {"admin"} Return?permissions | {"admin"} ने क्या लौटाया?permissions | {"admin"} 返回了什么?

A new frozenset with 4 items — the result takes the type of the left operand. permissions itself still has 3 items. We print the type and length here because printing the frozenset itself would show its strings in a random order.

4 items वाला एक नया frozenset — result का type बाएँ operand जैसा होता है। permissions में अब भी 3 items हैं। यहाँ type और length print किए गए हैं, क्योंकि frozenset को सीधे print करने पर strings random क्रम में दिखतीं।

一个有 4 个元素的新 frozenset — 结果的类型跟 左边 的操作数相同。permissions 本身仍然只有 3 个元素。这里打印类型和长度,是因为直接打印 frozenset 会以随机顺序显示字符串。

Try It — Frozenset Labकरके देखें — Frozenset Lab动手试试 — Frozenset 实验室

A small Python console with two variables: a frozenset perms and an empty set bundles. Click the lines in order, or type your own. Watch which ones Python blocks, and why.

दो variables वाला छोटा Python console: एक frozenset perms और एक खाली set bundles। Lines को क्रम से click करें, या अपनी लिखें। देखें Python किन्हें रोकता है, और क्यों।

一个带两个变量的小 Python 控制台:frozenset perms 和空 set bundles。按顺序点击这些行,或自己输入。观察 Python 拦下了哪些,以及原因。

🧊 Frozenset LabUnchangeable, hashable — can live inside sets and be dict keys.न बदलने वाला, hashable — sets के अंदर रह सकता है और dict key बन सकता है।不可变、可哈希 — 可以放进 set,也可以做 dict 的 key。
Try:आज़माएँ:试试:

SectionSection第 12 节

Practical Real-World Examples 🌍असल ज़िंदगी के उदाहरण 🌍实际应用示例 🌍

Example 1 — Instant Deduplication of a Listउदाहरण 1 — List से तुरंत Duplicates हटाना示例 1 — 一步给 list 去重

emails = ["alice@ex.com", "bob@ex.com", "alice@ex.com",
          "eve@ex.com", "bob@ex.com"]

# One line — order NOT kept (it can change from run to run)
unique_emails = list(set(emails))
print(len(unique_emails), "unique")

# If order matters, keep the first time each one appears with dict.fromkeys()
unique_ordered = list(dict.fromkeys(emails))
print(unique_ordered)
OUTPUT
3 unique ['alice@ex.com', 'bob@ex.com', 'eve@ex.com']

list(set(emails)) loses the order, so its printed order changes from run to run. dict.fromkeys() keeps the first time each email appears, because dicts remember insertion order (Python 3.7+).

list(set(emails)) क्रम खो देता है, इसलिए उसका print क्रम हर run में बदलता है। dict.fromkeys() हर email के पहली बार आने का क्रम रखता है, क्योंकि dicts डालने का क्रम याद रखते हैं (Python 3.7+)।

list(set(emails)) 会丢失顺序,所以它的打印顺序每次运行都会变。dict.fromkeys() 保留每个邮箱 第一次 出现的顺序,因为 dict 会记住插入顺序(Python 3.7+)。

Example 2 — Permission Checkingउदाहरण 2 — Permission जाँच示例 2 — 权限检查

required_perms  = {"read", "write"}
user_perms      = {"read", "write", "delete", "share"}

# Does the user have EVERY required permission?
if required_perms <= user_perms:
    print("Access granted")
else:
    missing = required_perms - user_perms
    print(f"Missing: {missing}")
OUTPUT
Access granted

Example 3 — Tag-Based Recommendationsउदाहरण 3 — Tags पर आधारित सुझाव示例 3 — 基于标签的推荐

user_tags    = {"python", "data-science", "ml", "stats"}
article_tags = {"python", "ml", "deep-learning"}

# Match score = shared tags / all tags
overlap = user_tags & article_tags
score = len(overlap) / len(user_tags | article_tags)

print(f"Common interests: {sorted(overlap)}")
print(f"Jaccard similarity: {score:.2%}")
OUTPUT
Common interests: ['ml', 'python'] Jaccard similarity: 40.00%
Jaccard
|A ∩ B| ÷ |A ∪ B| = 2 ÷ 5 = 0.40
Shared tags divided by all tags. 1.0 means the same tags; 0.0 means nothing in common.
साझा tags को कुल tags से भाग दें। 1.0 यानी बिल्कुल एक जैसे tags; 0.0 यानी कुछ भी साझा नहीं।
共同标签数除以全部标签数。1.0 表示标签完全相同;0.0 表示没有共同点。

Example 4 — Finding What Changedउदाहरण 4 — क्या बदला, यह खोजना示例 4 — 找出变化

old_snapshot = {"config.yaml", "main.py", "utils.py", "data.csv"}
new_snapshot = {"config.yaml", "main.py", "helpers.py", "data.csv"}

added     = new_snapshot - old_snapshot
removed   = old_snapshot - new_snapshot
unchanged = old_snapshot & new_snapshot

print(f"Added:     {added}")
print(f"Removed:   {removed}")
print(f"Unchanged: {sorted(unchanged)}")
OUTPUT
Added: {'helpers.py'} Removed: {'utils.py'} Unchanged: ['config.yaml', 'data.csv', 'main.py']

Example 5 — Fast Filtering Against a Blocklistउदाहरण 5 — Blocklist से तेज़ छँटाई示例 5 — 用黑名单快速过滤

import time

# A million user IDs coming through
incoming_ids = range(1_000_000)

# 50,000 banned IDs — as a SET for O(1) lookup
banned = set(range(0, 1_000_000, 20))

start = time.perf_counter()
allowed = [uid for uid in incoming_ids if uid not in banned]
secs = time.perf_counter() - start

print(f"Allowed: {len(allowed):,}")
print(f"Blocked: {len(banned):,}")
print(f"Time with a set: {secs:.2f} s")
OUTPUT
Allowed: 950,000 Blocked: 50,000 Time with a set: 0.09 s
⚡
Why This Is Fastयह तेज़ क्यों है为什么这么快

That example does 1 million not in checks against a 50,000-item blocklist. With a list, that is about 49 billion comparisons — we measured a sample and it works out to roughly 5 minutes. With a set it is 1 million hash lookups: 0.06 seconds here. Same code, one type changed, thousands of times faster.

यह उदाहरण 50,000 items वाली blocklist के सामने 10 लाख not in जाँचें करता है। List के साथ यह लगभग 49 अरब तुलनाएँ हैं — हमने एक नमूना नापा और यह लगभग 5 मिनट बैठता है। Set के साथ यह 10 लाख hash lookups हैं: यहाँ 0.06 सेकंड। वही code, बस एक type बदला, और हज़ारों गुना तेज़।

这个示例对一个 50,000 项 的黑名单做了 100 万 次 not in 检查。用 list 大约要 490 亿 次比较 — 我们实测了一个样本,推算约为 5 分钟。用 set 则是 100 万次 hash 查找:这里只用了 0.06 秒。同样的代码,只换了一个类型,快了几千倍。

Try It — Pattern Stepperकरके देखें — Pattern Stepper动手试试 — 模式步进器

Step through the real-world patterns one line at a time. Edit the inputs to test your own data. The first tab shows the classic "remove duplicates but keep the order" loop, which pairs a set with a list.

असल ज़िंदगी के patterns को एक-एक line करके चलाएँ। अपने data से जाँचने के लिए inputs बदलें। पहला tab मशहूर "duplicates हटाओ पर क्रम रखो" loop दिखाता है, जिसमें set और list साथ काम करते हैं।

一行一行地执行这些实际模式。修改输入来测试你自己的数据。第一个标签页展示经典的 "去重但保留顺序" 循环,它把 set 和 list 搭配使用。

🔁 Pattern StepperLine by line: see every set and list change.Line दर line: हर set और list का बदलाव देखें।逐行执行:查看每个 set 和 list 的变化。
outputoutput输出

SectionSection第 13 节

Performance — List vs Set for Membership 🏁Performance — Membership में List बनाम Set 🏁性能 — 成员检查中的 list 与 set 🏁

import timeit

# Same 100,000 items — stored as list vs set
data_list = list(range(100_000))
data_set  = set(data_list)

# Worst case for the list: search for the last item
target = 99_999

t_list = timeit.timeit(lambda: target in data_list, number=10_000)
t_set  = timeit.timeit(lambda: target in data_set,  number=10_000)

print(f"List lookup: {t_list:.4f}s")
print(f"Set lookup:  {t_set:.4f}s")
print(f"Set is about {t_list / t_set:,.0f}x faster")
OUTPUT
List lookup: 6.1304s Set lookup: 0.0004s Set is about 14,865x faster

Real run on Python 3.13.16. The ratio depends on your machine, but the set always wins by thousands of times for this worst case.

Python 3.13.16 पर असली run। अनुपात आपकी मशीन पर निर्भर है, पर इस सबसे बुरे मामले में set हमेशा हज़ारों गुना आगे रहता है।

在 Python 3.13.16 上的真实运行。倍数取决于你的机器,但在这种最坏情况下,set 总是快几千倍。

OperationOperation操作ListSetWinnerविजेता胜者
Access by indexIndex से पहुँच按索引访问O(1)Not supportedसमर्थित नहीं不支持List
Membership (in)Membership (in)成员检查(in)O(n)O(1) averageऔसतन O(1)平均 O(1)Set
Insertडालना插入O(1) appendO(1) appendO(1) appendO(1) add, averageO(1) add, औसतन平均 O(1) addTieबराबर平手
Delete by valueValue से हटाना按值删除O(n)O(1) discard, averageO(1) discard, औसतन平均 O(1) discardSet
Remove duplicatesDuplicates हटाना去重O(n²) naiveO(n²) सीधा तरीकाO(n²) 朴素做法O(n) built inO(n) built-inO(n) 内置Set
Keeps orderक्रम रखता है保持顺序Yesहाँ是Noनहीं否List
Allows duplicatesDuplicates की इजाज़त允许重复Yesहाँ是Noनहीं否Dependsज़रूरत पर看需求
MemoryMemory内存Lowकम低≈ 5× more for 100,000 ints (4.2 MB vs 0.8 MB)100,000 ints के लिए ≈ 5 गुना (4.2 MB बनाम 0.8 MB)100,000 个 int 约多 5 倍(4.2 MB 对 0.8 MB)List

Memory is sys.getsizeof() of the container only: a set keeps a hash table with empty slots and a stored hash per item, so it needs more room than a list.

Memory सिर्फ़ container का sys.getsizeof() है: set खाली slots वाली hash table और हर item का hash रखता है, इसलिए उसे list से ज़्यादा जगह चाहिए।

内存只算容器本身的 sys.getsizeof():set 要维护一张带空 slot 的哈希表,还要为每个元素存 hash,所以比 list 占更多空间。


SectionSection第 14 节

When NOT to Use a Set 🚫Set कब इस्तेमाल न करें 🚫什么时候不要用 set 🚫

🚫
You Need Orderआपको क्रम चाहिए你需要顺序
Rankings, timelines, sequencesRankings, समय-रेखा, क्रम排名、时间线、序列
Sets have no reliable order. If you need "the third item" or "the newest event first", use a list — or a dict, which keeps insertion order in Python 3.7+.
Sets का कोई भरोसेमंद क्रम नहीं होता। अगर आपको "तीसरा item" या "सबसे नई घटना पहले" चाहिए, तो list इस्तेमाल करें — या dict, जो Python 3.7+ में डालने का क्रम रखता है।
set 没有可靠的顺序。如果你需要 "第三个元素" 或 "最新的事件排第一",请用 list — 或者 dict,它在 Python 3.7+ 中保持插入顺序。
📑
You Need Countsआपको गिनती चाहिए你需要计数
How many times did X appear?X कितनी बार आया?X 出现了几次?
Sets drop duplicates. If frequency matters — word counts, event tallies, stock levels — use collections.Counter, not a set.
Sets duplicates हटा देते हैं। अगर गिनती मायने रखती है — शब्द गिनती, घटनाओं का हिसाब, stock — तो collections.Counter इस्तेमाल करें, set नहीं।
set 会丢掉重复项。如果频率很重要 — 词频、事件统计、库存 — 请用 collections.Counter,而不是 set。
🔒
Items Are Not HashableItems Hashable नहीं हैं元素不可哈希
Lists, dicts, other setsLists, dicts, दूसरे setslist、dict、其他 set
You cannot store lists, dicts or sets inside a set — Python raises TypeError: unhashable type. Convert them to tuples or frozensets first, or use a different structure.
आप set में lists, dicts या sets नहीं रख सकते — Python TypeError: unhashable type देता है। पहले उन्हें tuples या frozensets में बदलें, या कोई दूसरी संरचना इस्तेमाल करें।
你不能把 list、dict 或 set 放进 set — Python 会抛出 TypeError: unhashable type。先把它们转换成 tuple 或 frozenset,或者换一种数据结构。
# Lists inside a set fail with TypeError: unhashable type
try:
    bad = {[1, 2], [3, 4]}
except TypeError as e:
    print(f"Nope: {e}")

# FIX — convert inner lists to tuples (immutable, hashable)
good = {(1, 2), (3, 4)}
print(good)                            # works!

# A set inside a set fails too — use frozenset
try:
    nested = {{1, 2}}
except TypeError as e:
    print(f"Nope: {e}")
print({frozenset({1, 2})})
OUTPUT
Nope: unhashable type: 'list' {(1, 2), (3, 4)} Nope: unhashable type: 'set' {frozenset({1, 2})}

SectionSection第 15 节

Complete Method Reference 📚सभी Methods की सूची 📚方法完整参考 📚

Method / OperatorMethod / Operator方法 / 运算符What It Doesक्या करता है作用Changes s?s बदलता है?修改 s?
s.add(x)Add one itemएक item जोड़ें加入一个元素Yesहाँ是
s.update(*iters) / s |= tAdd many itemsकई items जोड़ें加入多个元素Yesहाँ是
s.remove(x)Remove x; KeyError if missingx हटाएँ; न हो तो KeyError删除 x;不存在时 KeyErrorYesहाँ是
s.discard(x)Remove x; silent if missingx हटाएँ; न हो तो चुप删除 x;不存在时不报错Yesहाँ是
s.pop()Remove and return any itemकोई भी item हटाकर लौटाएँ删除并返回任意元素Yesहाँ是
s.clear()Empty the setSet खाली करें清空 setYesहाँ是
s | t / s.union(*iters)Union — all itemsUnion — सभी items并集 — 所有元素Noनहीं否
s & t / s.intersection(*iters)Intersection — common items onlyIntersection — सिर्फ़ साझा items交集 — 只要共同元素Noनहीं否
s - t / s.difference(*iters)Items in s but not in ts में, पर t में नहीं在 s 中但不在 t 中Noनहीं否
s ^ t / s.symmetric_difference(t)In s or t, but not boths या t में, दोनों में नहीं在 s 或 t 中,但不同时在两者Noनहीं否
s.intersection_update(*iters) / s &= tKeep only common itemsसिर्फ़ साझा items रखें只保留共同元素Yesहाँ是
s.difference_update(*iters) / s -= tRemove items found in tt में मिले items हटाएँ删除 t 中有的元素Yesहाँ是
s.symmetric_difference_update(t) / s ^= tToggle: XOR into sToggle: s में XOR切换:异或到 s 中Yesहाँ是
s <= t / s.issubset(t)Is s a subset of t?क्या s, t का subset है?s 是 t 的子集吗?Noनहीं否
s < tStrict subset (s ⊂ t and s ≠ t)Strict subset (s ⊂ t और s ≠ t)真子集(s ⊂ t 且 s ≠ t)Noनहीं否
s >= t / s.issuperset(t)Is s a superset of t?क्या s, t का superset है?s 是 t 的超集吗?Noनहीं否
s > tStrict superset (s ⊃ t and s ≠ t)Strict superset (s ⊃ t और s ≠ t)真超集(s ⊃ t 且 s ≠ t)Noनहीं否
s.isdisjoint(t)Do s and t share nothing?क्या s और t में कुछ साझा नहीं?s 和 t 没有共同元素吗?Noनहीं否
s.copy()Shallow copyShallow copy浅拷贝Noनहीं否
len(s)Number of itemsItems की संख्या元素个数Noनहीं否
x in sMembership test — O(1) on averageMembership जाँच — औसतन O(1)成员检查 — 平均 O(1)Noनहीं否

Python 3.13.16 sets have 17 public methods. The (*iters) methods accept several iterables at once, for example s.union([1], (2,), "ab"). A frozenset has only the 8 methods that do not change it.

Python 3.13.16 के sets में 17 public methods हैं। (*iters) वाले methods एक साथ कई iterables लेते हैं, जैसे s.union([1], (2,), "ab")। Frozenset में सिर्फ़ वे 8 methods हैं जो उसे बदलते नहीं।

Python 3.13.16 的 set 有 17 个公共方法。带 (*iters) 的方法可以一次接收多个可迭代对象,例如 s.union([1], (2,), "ab")。frozenset 只有不修改自身的 8 个方法。


SectionSection第 16 节

Golden Rules 🏆सुनहरे नियम 🏆黄金法则 🏆

🔑 Sets — Rules to RememberSets — याद रखने वाले नियमSet — 必须记住的规则
1
Use a set whenever you ask "is X in this collection?" more than once. Building the set costs one pass; every lookup after that is about one step. Even a few hundred lookups against a 10,000-item list justify converting it first.
जब भी "क्या X इस संग्रह में है?" एक से ज़्यादा बार पूछें, set इस्तेमाल करें। Set बनाने में एक बार पूरा पढ़ना पड़ता है; उसके बाद हर lookup लगभग एक कदम है। 10,000 items वाली list पर कुछ सौ lookups भी पहले set बनाने को सही ठहराते हैं।
只要你不止一次地问 "X 在这个集合里吗?",就用 set。建 set 只需遍历一遍;之后每次查找大约只要一步。即使只对一个 10,000 项的 list 查几百次,先转成 set 也值得。
2
An empty set is set(), never {}. Empty braces make a dict. The bug is silent until you call .add() and get an AttributeError.
खाली set set() है, कभी {} नहीं। खाली braces dict बनाते हैं। यह bug तब तक चुप रहता है जब तक .add() पर AttributeError न मिले।
空 set 是 set(),绝不是 {}。空花括号创建的是 dict。这个 bug 不会报错,直到你调用 .add() 得到 AttributeError。
3
Reach for set operations before writing nested loops. "Items in both" is a & b, not a double for loop. "Items in one but not the other" is a - b. Shorter, faster and clearer.
Nested loops लिखने से पहले set operations सोचें। "दोनों में मौजूद items" a & b है, दो for loops नहीं। "एक में है पर दूसरे में नहीं" a - b है। छोटा, तेज़ और साफ़।
写嵌套循环之前,先想想集合运算。"两边都有的元素" 就是 a & b,不需要双重 for 循环。"在一个里但不在另一个里" 就是 a - b。更短、更快、更清楚。
4
Never rely on set order. Small ints often print in number order because an int is its own hash, but strings change order on every run and the layout can change between Python versions. If order matters, use sorted(my_set).
Set के क्रम पर कभी भरोसा न करें। छोटे ints अक्सर संख्या के क्रम में print होते हैं क्योंकि int का hash वही संख्या है, पर strings का क्रम हर run में बदलता है और Python versions के बीच भी बदल सकता है। क्रम चाहिए तो sorted(my_set) इस्तेमाल करें।
永远不要依赖 set 的顺序。小整数常常按大小打印,是因为 int 的 hash 就是它本身;但字符串每次运行顺序都会变,不同 Python 版本的布局也可能变。需要顺序时用 sorted(my_set)。
5
Use discard for forgiving code, remove for strict code. Silent failures hide bugs — but so do needless crashes. Choose on purpose.
नरम code के लिए discard, सख़्त code के लिए remove। चुप्पी bugs छिपाती है — पर बेवजह crash भी। सोच-समझकर चुनें।
宽容的代码用 discard,严格的代码用 remove。悄无声息的失败会掩盖 bug — 不必要的崩溃也一样。有意识地选择。
6
Use frozenset when you need a set inside another set, or as a dict key. Only unchangeable, hashable things can be keys or items. That is the whole purpose of the frozen version.
जब set को दूसरे set के अंदर या dict key के रूप में चाहिए, तो frozenset इस्तेमाल करें। सिर्फ़ न बदलने वाली, hashable चीज़ें keys या items बन सकती हैं। Frozen रूप का पूरा मक़सद यही है।
需要把 set 放进另一个 set 或作为 dict 的 key 时,用 frozenset。只有不可变、可哈希的东西才能做 key 或元素。这正是 frozen 版本存在的意义。
7
For counting, use collections.Counter, not a set. A set throws away exactly the information — how many — that counting needs.
गिनती के लिए collections.Counter इस्तेमाल करें, set नहीं। Set ठीक वही जानकारी फेंक देता है — कितने — जो गिनती को चाहिए।
计数请用 collections.Counter,不要用 set。set 丢掉的恰恰是计数需要的信息 — 有多少个。
8
Do not mix True/False with 1/0 in one set. They are equal and share a hash, so {1, True} has only one item.
एक set में True/False को 1/0 के साथ न मिलाएँ। वे बराबर हैं और उनका hash एक है, इसलिए {1, True} में सिर्फ़ एक item है।
不要在一个 set 里混用 True/False 和 1/0。它们相等且 hash 相同,所以 {1, True} 只有一个元素。

Quick Checkछोटी जाँच小测验

Seven questions on sets. Pick an answer to see why.

Sets पर सात सवाल। जवाब चुनें और कारण देखें।

关于 set 的七道题。选择答案查看解释。

🎯
The Takeawayमुख्य सीख要点总结

A set is a hash table of unique, hashable items. Use it to remove duplicates, to test membership fast and to compare groups with |, &, - and ^. Write set() for an empty set, never trust its order, and use frozenset when a set must be hashable.

Set अनोखे, hashable items की hash table है। इसे duplicates हटाने, तेज़ membership जाँच और |, &, -, ^ से समूहों की तुलना के लिए इस्तेमाल करें। खाली set के लिए set() लिखें, उसके क्रम पर कभी भरोसा न करें, और जब set को hashable होना हो तो frozenset इस्तेमाल करें।

set 是一张存放不重复、可哈希元素的哈希表。用它来 去重、快速检查成员,以及用 |、&、-、^ 比较集合。空 set 写 set(),永远不要依赖它的顺序,需要可哈希时用 frozenset。

🐍 Try Python Yourself

Write, run and visualize Python step by step. No install needed.