Intermediate Python 📂 Comprehensions · 1 of 1 296 min read

Python List, Dict & Set Comprehensions

Master Python's most Pythonic feature — comprehensions. This tutorial covers list, dict, and set comprehensions from first principles, with side-by-side loop comparisons, filtering vs transforming with if/else, nested patterns, real-world data cleaning examples, performance benchmarks vs for loops and map(), generator expressions for huge datasets, and the golden rules that keep your one-liners readable.

🌐
SectionSection第 01 节

The Story That Explains Comprehensions 🧃Comprehensions समझाने वाली कहानी 🧃一个讲清推导式的故事 🧃

The Assembly Line vs the Single ChefAssembly Line बनाम अकेला Chef流水线 vs 单个厨师
Imagine you run a juice shop and 100 apples sit on your counter. Every apple must be washed, sliced and pressed. You have two choices.

Option A — the old kitchen way: grab an empty crate. Pick up apple #1, wash it, slice it, drop it in the crate. Pick up apple #2, repeat. Four lines of instructions for something simple.

Option B — the assembly line: "Every apple on this counter, washed and pressed, into that crate — go." One sentence. Same result.

That is the difference between a for loop and a comprehension. Same output — one is a recipe, the other is a description of the result.
सोचिए आप juice की दुकान चलाते हैं और counter पर 100 सेब रखे हैं। हर सेब धोना, काटना और निचोड़ना है। आपके पास दो रास्ते हैं।

रास्ता A — पुरानी रसोई का तरीका: एक ख़ाली टोकरी लो। सेब #1 उठाओ, धोओ, काटो, टोकरी में डालो। सेब #2 उठाओ, दोहराओ। एक आसान काम के लिए चार lines के निर्देश।

रास्ता B — assembly line: "इस counter का हर सेब, धोकर और निचोड़कर, उस टोकरी में — शुरू करो।" एक वाक्य। वही नतीजा।

यही फ़र्क़ है for loop और comprehension में। Output एक जैसा — एक रेसिपी है, दूसरा नतीजे का वर्णन।
想象你开了一家果汁店,柜台上放着 100 个苹果。每个苹果都要洗、切、榨。你有两种选择。

选项 A — 老厨房的做法:拿一个空箱子。拿起苹果 #1,洗、切、放进箱子。拿起苹果 #2,重复。为一件简单的事写了四行指令。

选项 B — 流水线:"把柜台上的每个苹果洗好榨好,放进那个箱子 — 开始。"一句话,结果相同。

这就是 for 循环 与 推导式 的区别。输出一样 — 一个是菜谱,另一个是对结果的描述。

A comprehension is Python's way of building a new collection — a list, dict or set — from an existing iterable in one readable expression. It replaces the classic "make an empty container → loop → append" pattern with one line that reads almost like English.

Comprehension Python का तरीका है जिससे किसी मौजूदा iterable से एक नया collection — list, dict या set — एक पढ़ने लायक expression में बनाया जाता है। यह पुराने "ख़ाली container बनाओ → loop → append" pattern की जगह एक line देता है जो लगभग अंग्रेज़ी जैसी पढ़ी जाती है।

推导式 是 Python 用一个易读的表达式、从已有可迭代对象构建新集合 — 列表、字典 或 集合 — 的方式。它用一行几乎像英语一样的代码,取代了经典的"建空容器 → 循环 → append"模式。

Three Parts of Every Comprehensionहर Comprehension के तीन हिस्से每个推导式的三个部分
Anatomy of a comprehension[n ** 2for n in numsif n > 3]① what each item becomes① हर item क्या बनेगा① 每个元素变成什么② where items come from② items कहाँ से आते हैं② 元素从哪里来③ which items to keep③ कौन-से items रखें③ 保留哪些元素→ list→ list→ 列表Python runs ② first, then ③, then ①, for every itemPython हर item के लिए पहले ②, फिर ③, फिर ① चलाता हैPython 对每个元素先运行 ②,再 ③,最后 ①

Read it as a sentence: "n squared, for each n in nums, if n is greater than 3." The brackets decide the container.

इसे वाक्य की तरह पढ़ें: "n का square, nums के हर n के लिए, अगर n 3 से बड़ा है।" Brackets container तय करते हैं।

把它当句子读:"n 的平方,对 nums 中的每个 n,如果 n 大于 3。"括号决定容器类型。

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

A for loop tells the reader how to build the collection. A comprehension tells the reader what the collection is. That shift from "how" to "what" is the Pythonic mindset. As a bonus, comprehensions are usually a little faster than the equivalent loop — Section 10 shows real measurements.

For loop पढ़ने वाले को बताता है कि collection कैसे बनाना है। Comprehension बताती है कि collection क्या है। "कैसे" से "क्या" की यह बदलाव ही Pythonic सोच है। साथ में, comprehensions आमतौर पर बराबर के loop से थोड़ी तेज़ होती हैं — Section 10 असली माप दिखाता है।

for 循环告诉读者 如何 构建集合;推导式告诉读者集合 是什么。从"如何"到"是什么"的转变,就是 Pythonic 的思维方式。额外的好处是,推导式通常比等价的循环稍快一些 — 第 10 节给出了真实测量结果。

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

Look for the interactive boxes: the Comprehension Machine (Section 06), the If-Position Lab (07), the Nested Loop Visualizer (08) and Lazy vs Eager with a memory meter (11). Every result they show was produced by real Python.

Interactive डिब्बे खोजें: Comprehension Machine (Section 06), If-Position Lab (07), Nested Loop Visualizer (08) और memory meter के साथ Lazy vs Eager (11)। इनका हर नतीजा असली Python से बना है।

请留意这些互动框:Comprehension Machine(第 06 节)、If-Position Lab(07)、Nested Loop Visualizer(08)以及带内存表的 Lazy vs Eager(11)。它们显示的每个结果都由真实 Python 生成。


SectionSection第 02 节

The Universal Syntax 🧠सबके लिए एक Syntax 🧠通用语法 🧠

List, dict and set comprehensions share the same skeleton. Learn one shape and you know all three. Only the brackets and the output part change.

List, dict और set comprehensions का ढाँचा एक ही है। एक आकार सीखें और तीनों आ जाते हैं। सिर्फ़ brackets और output वाला हिस्सा बदलता है।

列表、字典和集合推导式共用同一个骨架。学会一种,三种都会了。只有括号和输出部分不同。

🧠 The Comprehension BlueprintComprehension का नक़्शा推导式蓝图
Output
What each element looks like — an expression, a transformation, or a key: value pair. हर element कैसा दिखेगा — एक expression, एक बदलाव, या key: value जोड़ी। 每个元素的样子 — 一个表达式、一个转换,或一个 key: value 对。
For
Where the elements come from — for item in iterable. You can have more than one. Elements कहाँ से आते हैं — for item in iterable। एक से ज़्यादा हो सकते हैं। 元素从哪里来 — for item in iterable。可以有多个。
If
Optional filter — if condition keeps only matching items. वैकल्पिक filter — if condition सिर्फ़ match करने वाले items रखता है। 可选的过滤 — if condition 只保留符合条件的元素。
BracketsBrackets括号
The container — [ ] list, { } set, {k: v} dict, ( ) generator. Container — [ ] list, { } set, {k: v} dict, ( ) generator। 容器 — [ ] 列表,{ } 集合,{k: v} 字典,( ) 生成器。
📚
List ComprehensionList Comprehension列表推导式
[expr for x in it]
Square brackets. Returns a list — ordered, indexable, duplicates allowed. The default choice for a sequence of results.
Square brackets। एक list लौटाती है — क्रम वाली, index वाली, duplicates की इजाज़त। नतीजों के क्रम के लिए default पसंद।
方括号。返回 列表 — 有序、可索引、允许重复。需要一串结果时的默认选择。
🔑
Dict ComprehensionDict Comprehension字典推导式
{k: v for x in it}
Curly braces with one colon between key and value. Returns a dict. Use it when each item becomes a key-value pair.
Curly braces, key और value के बीच एक colon। एक dict लौटाती है। जब हर item एक key-value जोड़ी बने, तब इस्तेमाल करें।
花括号,键与值之间 一个冒号。返回 字典。当每个元素变成一个键值对时使用。
🎯
Set ComprehensionSet Comprehension集合推导式
{expr for x in it}
Curly braces, no colon. Returns a set — unique elements, no fixed order. Perfect for removing duplicates in one line.
Curly braces, कोई colon नहीं। एक set लौटाती है — अनोखे elements, कोई तय क्रम नहीं। एक line में duplicates हटाने के लिए बढ़िया।
花括号,没有冒号。返回 集合 — 元素唯一,没有固定顺序。一行去重的利器。

SectionSection第 03 节

List Comprehensions — The Workhorse 🐎List Comprehensions — मेहनती घोड़ा 🐎列表推导式 — 主力军 🐎

List comprehensions are the most common kind. Use one anywhere you would otherwise write a for loop that appends to a list.

List comprehensions सबसे आम हैं। जहाँ भी आप list में append करने वाला for loop लिखते, वहाँ इसे इस्तेमाल करें।

列表推导式最常见。凡是你本来要写一个往列表 append 的 for 循环的地方,都可以用它。

The Loop You Have Always Writtenवह Loop जो आप हमेशा लिखते आए हैं你一直在写的循环

# The old way - 4 lines to square 10 numbers
squares = []
for n in range(10):
    squares.append(n ** 2)

print(squares)
OUTPUT
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

The Comprehension That Replaces Itउसकी जगह लेने वाली Comprehension取代它的推导式

# One line. Same result. Clearer intent.
squares = [n ** 2 for n in range(10)]

print(squares)
OUTPUT
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Adding a FilterFilter जोड़ना加上过滤

# Only even numbers, squared
even_squares = [n ** 2 for n in range(10) if n % 2 == 0]

# Cleaning a list of user inputs
raw = ["  Aarav ", "", "Meera", None, "  Kabir", "   "]
clean = [name.strip() for name in raw if name and name.strip()]

print(even_squares)
print(clean)
OUTPUT
[0, 4, 16, 36, 64] ['Aarav', 'Meera', 'Kabir']

Notice the filter if name and name.strip(): name alone drops None and "", and name.strip() also drops " " (only spaces). Without it, an empty string would sneak into the result.

Filter if name and name.strip() पर ध्यान दें: अकेला name, None और "" हटाता है, और name.strip(), " " (सिर्फ़ spaces) भी हटाता है। इसके बिना एक ख़ाली string नतीजे में घुस जाती।

注意过滤条件 if name and name.strip():单独的 name 能去掉 None 和 "",name.strip() 还能去掉 " "(只有空格)。少了它,一个空字符串就会混进结果。

🔑
Read It Left to Right — in Englishबाएँ से दाएँ पढ़ें — अंग्रेज़ी में从左到右用英语读

[n**2 for n in range(10) if n % 2 == 0] reads as: "n squared, for each n in range 10, where n is even." If you can read your comprehension out loud like a sentence, it is Pythonic. If you can't, turn it back into a loop.

[n**2 for n in range(10) if n % 2 == 0] ऐसे पढ़ी जाती है: "n का square, range 10 के हर n के लिए, जहाँ n सम है।" अगर आप अपनी comprehension को वाक्य की तरह बोलकर पढ़ सकें, तो वह Pythonic है। न पढ़ सकें, तो उसे वापस loop बना दें।

[n**2 for n in range(10) if n % 2 == 0] 读作:"n 的平方,对 range 10 中的每个 n,当 n 为偶数时。"如果能像句子一样把推导式读出来,它就是 Pythonic 的。读不出来,就改回循环。


SectionSection第 04 节

Dict Comprehensions — Building Mappings 🔑Dict Comprehensions — Mappings बनाना 🔑字典推导式 — 构建映射 🔑

Dict comprehensions are perfect for transforming, inverting or filtering key-value data. The shape is the same as a list comprehension, but the output is a key: value pair.

Dict comprehensions key-value data को बदलने, उलटने या filter करने के लिए बढ़िया हैं। आकार list comprehension जैसा ही है, पर output एक key: value जोड़ी है।

字典推导式非常适合转换、反转或过滤键值数据。形状与列表推导式相同,只是输出是一个 key: value 对。

Building a Lookup TableLookup Table बनाना构建查找表

# Number -> its square (classic use case)
square_map = {n: n ** 2 for n in range(6)}
print(square_map)
OUTPUT
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Inverting a Dict (Keys ↔ Values)Dict उलटना (Keys ↔ Values)反转字典(键 ↔ 值)

country_capital = {"India": "New Delhi", "France": "Paris", "Japan": "Tokyo"}

# Flip it - capitals become keys
capital_country = {v: k for k, v in country_capital.items()}
print(capital_country)

# Careful: if two keys share a value, the LAST one wins
team = {"Aarav": "red", "Meera": "blue", "Kabir": "red"}
by_colour = {colour: name for name, colour in team.items()}
print(by_colour)          # Aarav was silently overwritten
OUTPUT
{'New Delhi': 'India', 'Paris': 'France', 'Tokyo': 'Japan'} {'red': 'Kabir', 'blue': 'Meera'}
⚠️
Inverting Can Lose Dataउलटने से Data खो सकता है反转可能丢失数据

Dict keys must be unique. When two items produce the same key, the last one silently wins — no error, no warning. Above, "Aarav" vanished. If values can repeat, collect lists instead (see the grouping example in Section 09).

Dict keys अनोखी होनी चाहिए। जब दो items एक ही key बनाएँ, तो आख़िरी वाली चुपचाप जीत जाती है — न error, न चेतावनी। ऊपर "Aarav" ग़ायब हो गया। अगर values दोहरा सकती हैं, तो lists जमा करें (Section 09 का grouping उदाहरण देखें)।

字典的键必须唯一。当两个元素产生同一个键时,最后一个会悄悄胜出 — 不报错,不警告。上面的 "Aarav" 就消失了。如果值可能重复,请改为收集列表(见第 09 节的分组示例)。

Filtering a Dict by ValueValue से Dict Filter करना按值过滤字典

prices = {"apple": 120, "bread": 45, "milk": 60, "paneer": 420}

# Keep items under Rs 100
affordable = {item: price for item, price in prices.items() if price < 100}

print(affordable)
OUTPUT
{'bread': 45, 'milk': 60}

Building a Dict from Two Listsदो Lists से Dict बनाना用两个列表构建字典

names = ["Aarav", "Meera", "Kabir"]
scores = [85, 92, 78]

# zip() pairs them; the comprehension builds the dict
report = {name: score for name, score in zip(names, scores)}
print(report)

# For a plain pairing, dict(zip(...)) does the same job
print(dict(zip(names, scores)))
OUTPUT
{'Aarav': 85, 'Meera': 92, 'Kabir': 78} {'Aarav': 85, 'Meera': 92, 'Kabir': 78}
📈
The One-Colon Ruleएक-Colon का नियम一个冒号规则

A dict comprehension has exactly one colon in its output part — between key and value. Everything else is the same as a list comprehension. Forget the colon and you get a set comprehension (or a SyntaxError, as Section 07 shows).

Dict comprehension के output हिस्से में ठीक एक colon होता है — key और value के बीच। बाक़ी सब list comprehension जैसा है। Colon भूलें तो आपको set comprehension मिलती है (या SyntaxError, जैसा Section 07 दिखाता है)।

字典推导式的输出部分 恰好有一个冒号 — 位于键和值之间。其余部分与列表推导式相同。忘了冒号,你得到的就是集合推导式(或 SyntaxError,见第 07 节)。


SectionSection第 05 节

Set Comprehensions — Instant Deduplication 🎯Set Comprehensions — तुरंत Duplicates हटाना 🎯集合推导式 — 瞬间去重 🎯

Set comprehensions look like dict comprehensions without the colon. They build a set — a collection of unique items with no fixed order. Perfect whenever you want distinct results.

Set comprehensions बिना colon वाली dict comprehensions जैसी दिखती हैं। ये set बनाती हैं — अनोखे items का collection, बिना तय क्रम के। जब भी अलग-अलग नतीजे चाहिए, बढ़िया।

集合推导式看起来像 没有冒号 的字典推导式。它构建集合 — 元素唯一、没有固定顺序 的集合。需要去重结果时非常合适。

Unique Words from a Sentenceएक वाक्य के अनोखे शब्द句子中的不重复单词

text = "The quick brown fox jumps over the lazy dog the fox is quick"

# Unique words, all lowercase
unique_words = {w.lower() for w in text.split()}

print(unique_words)                  # order is not fixed!
print(sorted(unique_words))          # sort when you need a stable order
print(f"Distinct word count: {len(unique_words)}")
OUTPUT
{'brown', 'fox', 'the', 'over', 'is', 'quick', 'jumps', 'lazy', 'dog'} ['brown', 'dog', 'fox', 'is', 'jumps', 'lazy', 'over', 'quick', 'the'] Distinct word count: 9
🔀
Sets Have No Fixed OrderSet का कोई तय क्रम नहीं集合没有固定顺序

The order of a printed set of strings can change every time you run the program, because Python randomises string hashing for security. The first line of the output above will likely look different on your machine. When order matters, use sorted(...) like the second line.

Strings वाले set का print क्रम हर बार program चलाने पर बदल सकता है, क्योंकि Python सुरक्षा के लिए string hashing को random बनाता है। ऊपर के output की पहली line आपकी मशीन पर शायद अलग दिखेगी। जब क्रम मायने रखे, तो दूसरी line की तरह sorted(...) इस्तेमाल करें।

打印字符串集合时,顺序 每次运行程序都可能不同,因为 Python 出于安全考虑会随机化字符串哈希。上面输出的第一行在你的电脑上很可能不一样。顺序重要时,像第二行那样用 sorted(...)。

Unique File Extensions in a FolderFolder के अनोखे File Extensions文件夹中不重复的扩展名

files = [
    "report.pdf", "data.csv", "summary.pdf",
    "chart.png", "raw.csv", "notes.md", "logo.png",
]

# Grab the extension of each file, dedupe automatically
extensions = {f.split(".")[-1] for f in files}
print(sorted(extensions))
OUTPUT
['csv', 'md', 'pdf', 'png']
❌ Without a Set ComprehensionSet Comprehension के बिना不用集合推导式
LineLine行CodeCode代码
1exts = set()
2for f in files:
3    ext = f.split(".")[-1]
4    exts.add(ext)
4 lines, one accumulator4 lines, एक accumulator4 行,一个累加器
✅ With a Set ComprehensionSet Comprehension के साथ使用集合推导式
LineLine行CodeCode代码
1exts = {f.split(".")[-1]
    for f in files}
1 expression, no setup1 expression, कोई तैयारी नहीं1 个表达式,无需准备
🗂️
A Real-World Gotchaअसली दुनिया की एक चूक一个现实中的坑

f.split(".")[-1] gives "Makefile" for a file with no dot, and only "gz" for "backup.tar.gz". For real file names, use pathlib: Path(f).suffix is "" for "Makefile", and Path(f).suffixes gives [".tar", ".gz"].

f.split(".")[-1] बिना dot वाली file के लिए "Makefile" देता है, और "backup.tar.gz" के लिए सिर्फ़ "gz"। असली file names के लिए pathlib इस्तेमाल करें: "Makefile" के लिए Path(f).suffix "" है, और Path(f).suffixes [".tar", ".gz"] देता है।

对没有点号的文件,f.split(".")[-1] 会得到 "Makefile";对 "backup.tar.gz" 只得到 "gz"。处理真实文件名请用 pathlib:"Makefile" 的 Path(f).suffix 是 "",而 Path(f).suffixes 给出 [".tar", ".gz"]。


SectionSection第 06 节

How a Comprehension Runs — Step by Step ⚙️Comprehension कैसे चलती है — कदम-दर-कदम ⚙️推导式如何运行 — 一步一步 ⚙️

01
Get the iterableIterable लो取得可迭代对象
Python evaluates the iterable after the first in — the list, range, or dict.items() — once, before the loop starts.
Python पहले in के बाद वाला iterable — list, range, या dict.items() — loop शुरू होने से पहले एक बार evaluate करता है।
Python 在循环开始前,对第一个 in 之后的可迭代对象 — 列表、range 或 dict.items() — 求值一次。
02
Pull one item at a timeएक-एक item लो每次取一个元素
Each item is bound to the loop variable. For 1,000 items the body runs 1,000 times. It is still a Python loop — just a tighter one, with less overhead than a hand-written for with .append().
हर item loop variable से जुड़ता है। 1,000 items के लिए body 1,000 बार चलती है। यह फिर भी Python loop ही है — बस ज़्यादा कसा हुआ, हाथ से लिखे for और .append() से कम overhead वाला।
每个元素绑定到循环变量。1,000 个元素,主体就运行 1,000 次。它依然是 Python 循环 — 只是更紧凑,比手写的 for 加 .append() 开销更小。
03
Check the filter (if any)Filter जाँचो (अगर हो)检查过滤条件(如果有)
If an if clause exists, the item is tested. If the condition is false, the item is skipped — the output expression never runs for it.
अगर if clause है, तो item जाँचा जाता है। Condition false हो तो item छोड़ दिया जाता है — उसके लिए output expression कभी नहीं चलता।
如果有 if 子句,就检测这个元素。条件为假则跳过 — 输出表达式根本不会为它运行。
04
Evaluate the output expressionOutput expression चलाओ计算输出表达式
The expression on the left is computed for the current item. For a dict, both the key and the value expressions run.
बाईं ओर का expression मौजूदा item के लिए गिना जाता है। Dict के लिए key और value दोनों expressions चलते हैं।
左边的表达式对当前元素求值。字典的话,键和值两个表达式都会运行。
05
Store it in the containerContainer में रखो存入容器
The value is appended to the list, added to the set (duplicates ignored), or stored in the dict (an existing key is overwritten). When the iterable runs out, the finished container is returned.
Value list में append होती है, set में add होती है (duplicates अनदेखे), या dict में रखी जाती है (मौजूदा key overwrite होती है)। Iterable ख़त्म होने पर तैयार container लौटाया जाता है।
值被追加到列表、加入集合(忽略重复)或存入字典(已有的键被覆盖)。可迭代对象耗尽后,返回完成的容器。

Try It — Comprehension Machineकरके देखें — Comprehension Machine动手试试 — 推导式机器

Build any comprehension from the parts below, then press Play. Watch each item leave the conveyor, meet the filter, get transformed and land in the container. The equivalent for loop lights up in step. Try dups with a set, and n % 3 with {expr: n}, to see duplicates and overwritten keys.

नीचे के हिस्सों से कोई भी comprehension बनाएँ, फिर चलाएँ दबाएँ। हर item को conveyor छोड़ते, filter से मिलते, बदलते और container में पहुँचते देखें। बराबर का for loop साथ-साथ जलता है। Duplicates और overwrite होती keys देखने के लिए dups के साथ set, और n % 3 के साथ {expr: n} आज़माएँ।

用下面的部件搭出任意推导式,然后点 播放。看每个元素离开传送带、经过过滤、被转换、落入容器。等价的 for 循环会同步高亮。试试 dups 配 set,以及 n % 3 配 {expr: n},观察重复和被覆盖的键。

🏭 Comprehension MachinePick the parts. Watch every item travel.हिस्से चुनें। हर item का सफ़र देखें।选好部件,看每个元素的旅程。
sourcesource数据源
output
if
bracketsbrackets括号
output what each item becomesहर item क्या बनेगा每个元素变成什么for where items come fromitems कहाँ से आते हैं元素从哪里来if which items are keptकौन-से items रखे जाएँ保留哪些元素
the same thing as a for loopयही काम for loop से等价的 for 循环
🔒
Comprehensions Have Their Own ScopeComprehensions का अपना Scope होता है推导式有自己的作用域

The loop variable lives only inside the comprehension. After [n * n for n in range(4)], an outer n is untouched — Section 12 proves it. (In Python 2 it used to leak; Python 3 fixed that.)

Loop variable सिर्फ़ comprehension के अंदर रहता है। [n * n for n in range(4)] के बाद बाहर का n अछूता रहता है — Section 12 इसे साबित करता है। (Python 2 में यह बाहर रिसता था; Python 3 ने इसे ठीक किया।)

循环变量只存在于推导式内部。执行 [n * n for n in range(4)] 之后,外部的 n 不受影响 — 第 12 节会证明。(Python 2 中它会泄漏出去;Python 3 修复了这一点。)


SectionSection第 07 节

Conditionals — Filter vs Transform 🔀Conditionals — Filter बनाम Transform 🔀条件 — 过滤 vs 转换 🔀

An if can appear in two very different places in a comprehension. Mixing them up is the #1 beginner mistake.

Comprehension में if दो बिल्कुल अलग जगहों पर आ सकता है। इन्हें मिला देना शुरुआती लोगों की नंबर 1 ग़लती है।

if 可以出现在推导式中 两个完全不同的位置。把它们搞混是初学者的头号错误。

🔍
Filter (if at the end)Filter (अंत में if)过滤(if 在末尾)
[x for x in it if cond]
Decides whether each item is kept. Items that fail are dropped. Use it when you want fewer items than you started with.
तय करता है कि हर item रखा जाए या नहीं। Fail होने वाले हटा दिए जाते हैं। तब इस्तेमाल करें जब शुरुआत से कम items चाहिए।
决定每个元素 是否 保留。不通过的被丢弃。想要比原来更少的元素时使用。
🔄
Transform (if/else on the left)Transform (बाईं ओर if/else)转换(if/else 在左边)
[a if cond else b for x in it]
Decides what value each item becomes. Every item stays. Use it when you want the same number of items, shaped differently.
तय करता है कि हर item कौन-सी value बने। हर item रहता है। तब इस्तेमाल करें जब items उतने ही चाहिए, पर अलग आकार में।
决定每个元素 变成什么值。所有元素都保留。想要数量不变、形态不同时使用。
🎯
Both at Onceदोनों एक साथ两者同时
[a if c1 else b for x in it if c2]
The filter (if c2 at the end) runs first; the survivors are then transformed (a if c1 else b). Powerful — read it twice before writing it.
Filter (अंत का if c2) पहले चलता है; बचे हुए फिर बदले जाते हैं (a if c1 else b)। ताक़तवर — लिखने से पहले दो बार पढ़ें।
先运行过滤(末尾的 if c2),再转换留下的元素(a if c1 else b)。很强大 — 写之前读两遍。

Side-by-Side Comparisonआमने-सामने तुलना并排比较

nums = [1, 2, 3, 4, 5, 6, 7, 8]

# FILTER: only keep even numbers -> shorter output
evens = [n for n in nums if n % 2 == 0]

# TRANSFORM: mark each number as "even" or "odd" -> same length
labels = ["even" if n % 2 == 0 else "odd" for n in nums]

# BOTH: label only numbers greater than 3
mixed = ["even" if n % 2 == 0 else "odd" for n in nums if n > 3]

print(evens)
print(labels)
print(mixed)
OUTPUT
[2, 4, 6, 8] ['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even'] ['even', 'odd', 'even', 'odd', 'even']

Try It — If-Position Labकरके देखें — If-Position Lab动手试试 — if 位置实验室

Pick a filter, a transform and where they go. The tiles show what happens to each of the numbers 1–8: dropped (✗), kept, or changed. The last two buttons are the broken forms — see the real error Python gives.

एक filter, एक transform और उनकी जगह चुनें। Tiles दिखाती हैं कि 1–8 की हर संख्या का क्या होता है: हटाई गई (✗), रखी गई, या बदली गई। आख़िरी दो buttons टूटे हुए रूप हैं — Python का असली error देखें।

选一个过滤、一个转换以及它们的位置。方块显示 1–8 每个数字的结果:被丢弃(✗)、保留或被改变。最后两个按钮是错误写法 — 看看 Python 给出的真实报错。

🔀 If-Position LabFilter decides IF an item stays. Transform decides WHAT it becomes.Filter तय करता है item रहे या नहीं। Transform तय करता है वह क्या बने।过滤决定元素是否留下,转换决定它变成什么。
filter
transform
layoutबनावट写法
output what each item becomesहर item क्या बनेगा每个元素变成什么for where items come fromitems कहाँ से आते हैं元素从哪里来if which items are keptकौन-से items रखे जाएँ保留哪些元素
numsnumsnums
resultनतीजा结果

Here are the three classic mistakes and the exact messages Python gives:

ये तीन मशहूर ग़लतियाँ हैं और Python के ठीक-ठीक संदेश:

下面是三个经典错误,以及 Python 给出的确切信息:

bad = [
    "[n if n > 3 for n in nums]",              # if/else on the left needs else
    "[n for n in nums if n > 3 else 0]",       # a filter cannot have else
    "{k, v for k, v in pairs}",                # missing colon in a dict
]
for src in bad:
    try:
        compile(src, "demo", "eval")
    except SyntaxError as e:
        print(f"{src:36} -> SyntaxError: {e.msg}")
OUTPUT
[n if n > 3 for n in nums] -> SyntaxError: expected 'else' after 'if' expression [n for n in nums if n > 3 else 0] -> SyntaxError: invalid syntax {k, v for k, v in pairs} -> SyntaxError: did you forget parentheses around the comprehension target?
⚠️
The Position Rule — Memorise Thisजगह का नियम — याद कर लें位置规则 — 务必记住

An if after the for is a filter — no else allowed. An if … else before the for is a conditional expression — the else is required. Mix them up and Python raises SyntaxError. Get this right and you will never fear comprehensions again.

for के बाद वाला if filter है — else की इजाज़त नहीं। for से पहले वाला if … else conditional expression है — else ज़रूरी है। इन्हें मिलाएँ तो Python SyntaxError देता है। यह सही कर लें तो comprehensions से कभी डर नहीं लगेगा।

for 之后 的 if 是过滤 — 不能有 else。for 之前 的 if … else 是条件表达式 — 必须有 else。搞混了 Python 就会抛出 SyntaxError。掌握这一点,你就再也不会怕推导式了。


SectionSection第 08 节

Nested Comprehensions — Flattening and Grids 🧮Nested Comprehensions — Flatten करना और Grids 🧮嵌套推导式 — 展平与网格 🧮

A comprehension can have several for clauses. The rule is simple: they run left to right in the same order as nested for loops written top to bottom.

एक comprehension में कई for clauses हो सकते हैं। नियम सरल है: वे बाएँ से दाएँ, उसी क्रम में चलते हैं जैसे ऊपर से नीचे लिखे nested for loops।

一个推导式可以有多个 for 子句。规则很简单:它们 从左到右运行,顺序与从上到下书写的嵌套 for 循环完全相同。

Flattening a Matrix (List of Lists → List)Matrix को Flatten करना (Lists की List → List)展平矩阵(列表的列表 → 列表)

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

# Outer loop first, inner loop second - same order as nested for loops
flat = [n for row in matrix for n in row]
print(flat)
OUTPUT
[1, 2, 3, 4, 5, 6, 7, 8, 9]
📑 Reading [n for row in matrix for n in row][n for row in matrix for n in row] पढ़ना读懂 [n for row in matrix for n in row]
1st1st第 1
for row in matrix — the outer loop; goes over each inner list. for row in matrix — बाहरी loop; हर अंदरूनी list पर चलता है। for row in matrix — 外层循环;遍历每个内部列表。
2nd2nd第 2
for n in row — the inner loop; goes over the current row. for n in row — अंदरूनी loop; मौजूदा row पर चलता है। for n in row — 内层循环;遍历当前行。
Out
n — each element, added to the final flat list. n — हर element, अंतिम flat list में जुड़ता है। n — 每个元素,加入最终的扁平列表。

Building a Matrix (a Comprehension Inside a Comprehension)Matrix बनाना (Comprehension के अंदर Comprehension)构建矩阵(推导式中的推导式)

# A 3x3 multiplication table - a list of lists
mult_table = [[i * j for j in range(1, 4)] for i in range(1, 4)]

for row in mult_table:
    print(row)

# Transpose: turn rows into columns
transposed = [[row[c] for row in mult_table] for c in range(3)]
print(transposed)
OUTPUT
[1, 2, 3] [2, 4, 6] [3, 6, 9] [[1, 2, 3], [2, 4, 6], [3, 6, 9]]

Careful — these two look alike but are different. [x for a in A for x in a] has two fors in one comprehension and gives a flat list. [[x for x in a] for a in A] puts a whole comprehension in the output part and gives a list of lists.

सावधान — ये दोनों एक जैसे दिखते हैं पर अलग हैं। [x for a in A for x in a] में एक comprehension में दो for हैं और यह flat list देता है। [[x for x in a] for a in A] output हिस्से में पूरी comprehension रखता है और lists की list देता है।

注意 — 这两种写法看似相同,其实不同。[x for a in A for x in a] 是一个推导式里有两个 for,得到 扁平 列表。[[x for x in a] for a in A] 把整个推导式放在输出部分,得到 列表的列表。

Cartesian Product (All Pairs)Cartesian Product (सारी जोड़ियाँ)笛卡尔积(所有组合)

colours = ["red", "blue"]
sizes = ["S", "M", "L"]

# Every colour x every size = 6 T-shirts
skus = [f"{c}-{s}" for c in colours for s in sizes]
print(skus)
OUTPUT
['red-S', 'red-M', 'red-L', 'blue-S', 'blue-M', 'blue-L']

Try It — Nested Loop Visualizerकरके देखें — Nested Loop Visualizer动手试试 — 嵌套循环可视化

Step through four nested comprehensions. The orange chip is the current value of each loop variable. Notice how the inner loop restarts every time the outer loop moves one step.

चार nested comprehensions को कदम-दर-कदम चलाएँ। नारंगी chip हर loop variable की मौजूदा value है। देखें कि बाहरी loop के एक कदम बढ़ते ही अंदरूनी loop फिर से शुरू होता है।

逐步执行四个嵌套推导式。橙色方块是每个循环变量的当前值。注意外层循环每前进一步,内层循环都会从头开始。

🧮 Nested Loop VisualizerFirst for = outer loop. Second for = inner loop.पहला for = बाहरी loop। दूसरा for = अंदरूनी loop।第一个 for = 外层循环,第二个 for = 内层循环。
the same thing as nested loopsयही काम nested loops से等价的嵌套循环
🚨
The Two-Level Ceilingदो-स्तर की छत两层上限

Two fors in one comprehension is fine. Three is hard to read. If you reach for triple nesting, stop and split it into a helper function or plain loops. Clever code that nobody can maintain is a liability, not an asset.

एक comprehension में दो for ठीक हैं। तीन पढ़ना मुश्किल है। अगर तिहरी nesting की ओर बढ़ें, तो रुकें और उसे helper function या सामान्य loops में बाँटें। ऐसा चालाक code जिसे कोई maintain न कर सके, बोझ है, संपत्ति नहीं।

一个推导式里两个 for 没问题。三个就难读了。如果你想写三层嵌套,停下来,把它拆成辅助函数或普通循环。没人能维护的"聪明"代码是负债,不是资产。


SectionSection第 09 节

Practical Real-World Examples 🛠️असली दुनिया के उदाहरण 🛠️实用的真实示例 🛠️

Example 1 — Cleaning Messy CSV Dataउदाहरण 1 — गंदे CSV Data को साफ़ करना示例 1 — 清洗杂乱的 CSV 数据

raw_rows = [
    "  Aarav, 25 , aarav@example.com  ",
    "Meera,30,meera@example.com",
    "  Kabir , 28,kabir@example.com  ",
    "",  # blank row
]

# Split, strip whitespace, skip blanks - all in one pass
clean = [
    [field.strip() for field in row.split(",")]
    for row in raw_rows if row.strip()
]

for row in clean:
    print(row)
OUTPUT
['Aarav', '25', 'aarav@example.com'] ['Meera', '30', 'meera@example.com'] ['Kabir', '28', 'kabir@example.com']

For real CSV files, use the built-in csv module — it handles commas inside quotes, which a simple split(",") cannot.

असली CSV files के लिए built-in csv module इस्तेमाल करें — यह quotes के अंदर के commas संभालता है, जो सीधा split(",") नहीं कर सकता।

处理真实 CSV 文件请用内置的 csv 模块 — 它能处理引号内的逗号,而简单的 split(",") 做不到。

Example 2 — Counting Word Frequenciesउदाहरण 2 — शब्दों की गिनती示例 2 — 统计词频

from collections import Counter

text = "the cat sat on the mat the cat is fat"
words = text.split()

# Works, but counts the whole list again for EVERY unique word
freq = {w: words.count(w) for w in words}
print(freq)

# Better: one pass, made for exactly this job
print(Counter(words).most_common(3))
OUTPUT
{'the': 3, 'cat': 2, 'sat': 1, 'on': 1, 'mat': 1, 'is': 1, 'fat': 1} [('the', 3), ('cat', 2), ('sat', 1)]
🐢
A Hidden Slowdownएक छिपी सुस्ती一个隐藏的慢点

{w: words.count(w) for w in words} looks neat, but count() scans the whole list for every word. With 100,000 words that is billions of steps. collections.Counter counts everything in one pass — use it for real data.

{w: words.count(w) for w in words} सुंदर दिखता है, पर count() हर शब्द के लिए पूरी list scan करता है। 100,000 शब्दों पर यह अरबों कदम हैं। collections.Counter एक ही बार में सब गिनता है — असली data के लिए इसे इस्तेमाल करें।

{w: words.count(w) for w in words} 看起来很简洁,但 count() 会为每个单词扫描整个列表。10 万个单词就是数十亿步。collections.Counter 一次遍历就能数完 — 真实数据请用它。

Example 3 — Grouping Users by Domainउदाहरण 3 — Domain के हिसाब से Users को समूह में रखना示例 3 — 按域名分组用户

emails = ["aarav@gmail.com", "meera@yahoo.com",
          "kabir@gmail.com", "dev@outlook.com",
          "isha@yahoo.com", "rohan@notgmail.com"]

# Split once into (user, domain) pairs
pairs = [e.split("@") for e in emails]

# Group users under each domain (sorted, so the order is stable)
grouped = {
    d: [user for user, dom in pairs if dom == d]
    for d in sorted({dom for _, dom in pairs})
}

for domain, users in grouped.items():
    print(f"{domain}: {users}")
OUTPUT
gmail.com: ['aarav', 'kabir'] notgmail.com: ['rohan'] outlook.com: ['dev'] yahoo.com: ['meera', 'isha']
🐛
Why Not e.endswith(d)?e.endswith(d) क्यों नहीं?为什么不用 e.endswith(d)?

A shorter version checks e.endswith(d). It has a bug: "rohan@notgmail.com".endswith("gmail.com") is True, so Rohan would appear under gmail.com too. Splitting on "@" and comparing the domain exactly avoids this. Sorting the domains also gives a stable order, because a set has none.

एक छोटा version e.endswith(d) जाँचता है। उसमें bug है: "rohan@notgmail.com".endswith("gmail.com") True है, इसलिए Rohan gmail.com के नीचे भी दिखता। "@" पर split करके domain की ठीक-ठीक तुलना से यह बचता है। Domains को sort करने से क्रम भी स्थिर रहता है, क्योंकि set का कोई क्रम नहीं होता।

更短的写法是检查 e.endswith(d)。它有个 bug:"rohan@notgmail.com".endswith("gmail.com") 为 True,Rohan 也会出现在 gmail.com 下。按 "@" 拆分并精确比较域名可以避免这个问题。对域名排序还能得到稳定顺序,因为集合本身没有顺序。

Example 4 — A Small Data Pipelineउदाहरण 4 — एक छोटी Data Pipeline示例 4 — 一个小型数据管道

transactions = [
    {"id": 1, "amount": 100, "status": "paid"},
    {"id": 2, "amount": 250, "status": "pending"},
    {"id": 3, "amount": 75,  "status": "paid"},
    {"id": 4, "amount": 500, "status": "paid"},
]

# IDs of paid transactions over Rs 100
big_paid = [t["id"] for t in transactions
            if t["status"] == "paid" and t["amount"] > 100]

# Total amount by status
statuses = sorted({t["status"] for t in transactions})
total_by_status = {
    s: sum(t["amount"] for t in transactions if t["status"] == s)
    for s in statuses
}

print("Big paid IDs:", big_paid)
print("Totals:      ", total_by_status)
OUTPUT
Big paid IDs: [4] Totals: {'paid': 675, 'pending': 250}

Note the generator expression inside sum(...) — no extra brackets needed. Section 11 explains why it uses less memory.

sum(...) के अंदर generator expression पर ध्यान दें — अतिरिक्त brackets की ज़रूरत नहीं। Section 11 बताता है कि यह कम memory क्यों लेता है।

注意 sum(...) 里的生成器表达式 — 不需要额外括号。第 11 节解释它为什么更省内存。


SectionSection第 10 节

Performance — Are Comprehensions Actually Faster? ⚡Performance — क्या Comprehensions सच में तेज़ हैं? ⚡性能 — 推导式真的更快吗?⚡

Usually, yes — but by less than people claim. Here is a real measurement: squaring 100,000 numbers, 100 times, four ways.

आमतौर पर हाँ — पर लोग जितना कहते हैं उससे कम। यह असली माप है: 100,000 संख्याओं का square, 100 बार, चार तरीकों से।

通常是的 — 但没有人们说的那么夸张。下面是真实测量:对 100,000 个数求平方,重复 100 次,四种写法。

import timeit

# Squaring 100,000 numbers - four different ways, 100 runs each
setup = "nums = range(100_000)"

tests = {
    "for loop + append": "result = []\nfor n in nums: result.append(n * n)",
    "list comprehension": "result = [n * n for n in nums]",
    "map + lambda": "result = list(map(lambda n: n * n, nums))",
    "generator into list": "result = list(n * n for n in nums)",
}
for name, stmt in tests.items():
    t = timeit.timeit(stmt, setup=setup, number=100)
    print(f"{name:20} {t:.3f}s")
OUTPUT (on the machine that built this page)
for loop + append 0.461s list comprehension 0.325s map + lambda 0.570s generator into list 0.506s
Measured Time — Shorter Is Fasterमापा गया समय — छोटा मतलब तेज़实测时间 — 越短越快
Measured timesfor loop + append0.461slist comprehension0.325smap + lambda0.570sgenerator into list0.506s

The list comprehension was the fastest here — about 1.4× faster than the loop with .append(). Your numbers will differ, but the ranking is usually the same.

यहाँ list comprehension सबसे तेज़ रही — .append() वाले loop से लगभग 1.4× तेज़। आपके numbers अलग होंगे, पर क्रम आमतौर पर वही रहता है।

这里列表推导式最快 — 约为带 .append() 的循环的 1.4 倍。你的数字会不同,但排名通常一致。

Approachतरीका写法Speedगति速度Readabilityपढ़ने में可读性When to useकब इस्तेमाल करें何时使用
ComprehensionComprehension推导式Fastest hereयहाँ सबसे तेज़这里最快Excellent for simple expressionsसरल expressions के लिए बेहतरीन简单表达式时极佳The default for building a collectionCollection बनाने का default构建集合时的默认选择
For loop + appendFor loop + appendfor 循环 + appendA bit slowerथोड़ा धीमा稍慢Best for multi-step logicकई कदमों वाले logic के लिए सबसे अच्छा多步骤逻辑最佳Side effects, try/except, break, many stepsSide effects, try/except, break, कई कदम副作用、try/except、break、多步骤
map() + lambdaSlower (a function call per item)धीमा (हर item पर function call)较慢(每个元素一次函数调用)Less readableकम पठनीय可读性较差With a ready-made function: map(str, nums) is fineतैयार function के साथ: map(str, nums) ठीक है配合现成函数:map(str, nums) 没问题
list( generator )list( generator )list(生成器)Slower than [...][...] से धीमा比 [...] 慢Fineठीक尚可Just write [...] insteadइसकी जगह सीधे [...] लिखें直接写 [...] 即可
⚡
Why Comprehensions WinComprehensions क्यों जीतती हैं推导式为什么更快

A loop with result.append(x) must look up the append method and call it on every turn. A list comprehension uses a special bytecode instruction (LIST_APPEND) instead, so there is no method lookup and no call. Since Python 3.12 (PEP 709), comprehensions are also inlined into the surrounding function, which removes the cost of creating a hidden function. The loop itself still runs in Python — it is just leaner.

result.append(x) वाले loop को हर चक्कर में append method ढूँढना और बुलाना पड़ता है। List comprehension इसकी जगह एक ख़ास bytecode instruction (LIST_APPEND) इस्तेमाल करती है, इसलिए न method lookup, न call। Python 3.12 (PEP 709) से comprehensions आसपास के function में inline भी होती हैं, जिससे एक छिपा function बनाने का ख़र्च हट जाता है। Loop फिर भी Python में ही चलता है — बस हल्का है।

带 result.append(x) 的循环每一轮都要查找并调用 append 方法。列表推导式改用专门的字节码指令(LIST_APPEND),没有方法查找也没有调用。从 Python 3.12(PEP 709)起,推导式还会被 内联 到所在函数中,省去了创建隐藏函数的开销。循环本身仍在 Python 中运行 — 只是更精简。


SectionSection第 11 节

Generator Expressions — The Lazy Cousin 🌱Generator Expressions — आलसी चचेरा भाई 🌱生成器表达式 — 懒惰的表亲 🌱

Swap the square brackets for round brackets and you get a generator expression. It looks like a list comprehension, but it produces values one at a time, only when asked — so it uses almost no memory, even for millions of items.

Square brackets की जगह गोल brackets लगाएँ और आपको generator expression मिलता है। यह list comprehension जैसा दिखता है, पर values एक-एक करके, सिर्फ़ माँगने पर बनाता है — इसलिए लाखों items के लिए भी लगभग कोई memory नहीं लेता।

把方括号换成 圆括号,就得到 生成器表达式。它看起来像列表推导式,但 一次只产生一个值,而且只在被请求时才产生 — 所以即使有几百万个元素,也几乎不占内存。

import sys, tracemalloc

N = 10_000_000

tracemalloc.start()
squares_list = [n ** 2 for n in range(N)]          # builds ALL values now
list_mb = tracemalloc.get_traced_memory()[0] / 1_000_000
del squares_list
tracemalloc.stop()

squares_gen = (n ** 2 for n in range(N))           # builds nothing yet
print(f"list comprehension:   {list_mb:,.0f} MB")
print(f"generator expression: {sys.getsizeof(squares_gen)} bytes")

# Both work with sum() - but only the generator is memory-safe
total = sum(n ** 2 for n in range(N))
print(f"Sum of squares 0-9,999,999: {total:,}")
OUTPUT
list comprehension: 409 MB generator expression: 200 bytes Sum of squares 0-9,999,999: 333,333,283,333,335,000,000

These numbers are real. The list needed about 409 MB; the generator object is 200 bytes and stays that size no matter how big N is. Both give the same sum.

ये numbers असली हैं। List को लगभग 409 MB चाहिए थे; generator object 200 bytes का है और N कितना भी बड़ा हो, उतना ही रहता है। दोनों एक ही जोड़ देते हैं।

这些数字是真实的。列表需要约 409 MB;生成器对象只有 200 字节,无论 N 多大都保持不变。两者求和结果相同。

Lazy Means "Not Until You Ask"आलसी मतलब "जब तक माँगो नहीं"懒惰就是"你不要就不算"

def square(n):
    print(f"  computing {n}")
    return n * n

print("list comprehension:")
lst = [square(n) for n in range(3)]       # all work happens NOW
print("built:", lst)

print("generator expression:")
gen = (square(n) for n in range(3))       # nothing computed yet
print("created")
print("next ->", next(gen))
print("next ->", next(gen))
print("rest ->", list(gen))
print("again ->", list(gen))              # exhausted: one-shot only
OUTPUT
list comprehension: computing 0 computing 1 computing 2 built: [0, 1, 4] generator expression: created computing 0 next -> 0 computing 1 next -> 1 computing 2 rest -> [4] again -> []

Try It — Lazy vs Eagerकरके देखें — Lazy बनाम Eager动手试试 — 惰性 vs 急切

Left: a list comprehension does all the work at once. Right: a generator does nothing until you call next(). Click the buttons and watch when computing … appears. Below, the memory meter shows measured sizes.

बाएँ: list comprehension सारा काम एक साथ करती है। दाएँ: generator तब तक कुछ नहीं करता जब तक आप next() न बुलाएँ। Buttons दबाएँ और देखें computing … कब आता है। नीचे memory meter नापे गए sizes दिखाता है।

左边:列表推导式一次做完所有工作。右边:生成器在你调用 next() 之前什么都不做。点按钮,看 computing … 何时出现。下方的内存表显示实测大小。

🌱 Lazy vs Eager[ ] builds everything now. ( ) builds one value per next().[ ] सब कुछ अभी बनाता है। ( ) हर next() पर एक value।[ ] 立刻全部构建,( ) 每次 next() 构建一个值。
[ ] list comprehension — eager[ ] list comprehension — eager[ ] 列表推导式 — 急切
( ) generator expression — lazy( ) generator expression — lazy( ) 生成器表达式 — 惰性
memory meter — real measurements (log scale)memory meter — असली माप (log scale)内存表 — 实测值(对数刻度)
📚 List ComprehensionList Comprehension列表推导式
Traitगुण特性Behaviourव्यवहार表现
BracketsBrackets括号[ ]
MemoryMemory内存Stores every itemहर item रखती है存储所有元素
Reusableदोबारा इस्तेमाल可重复使用Yes — loop over it many timesहाँ — कई बार loop करें是 — 可多次遍历
Extrasऔर其他len(), indexing, slicinglen(), indexing, slicinglen()、索引、切片
Best forकिसके लिए适合Small/medium data you use more than onceछोटा/मध्यम data जो एक से ज़्यादा बार इस्तेमाल हो多次使用的中小数据
🌱 Generator ExpressionGenerator Expression生成器表达式
Traitगुण特性Behaviourव्यवहार表现
BracketsBrackets括号( )
MemoryMemory内存One item at a timeएक बार में एक item一次一个元素
Reusableदोबारा इस्तेमाल可重复使用No — one pass onlyनहीं — सिर्फ़ एक बार否 — 只能遍历一次
Extrasऔर其他No len(), no indexinglen() नहीं, indexing नहीं没有 len(),不能索引
Best forकिसके लिए适合Huge data, streams, a single sum/max/anyबहुत बड़ा data, streams, एक बार का sum/max/any超大数据、流、一次性的 sum/max/any
💡
The Function-Argument ShortcutFunction-Argument वाला Shortcut函数参数的简写

When a generator expression is the only argument to a function, you can drop its own brackets: sum(n ** 2 for n in range(1000)) is clean; sum((n ** 2 for n in range(1000))) is legal but noisy. With a second argument, the brackets are required: sorted((n % 7 for n in nums), reverse=True).

जब generator expression किसी function का इकलौता argument हो, तो उसके अपने brackets हटा सकते हैं: sum(n ** 2 for n in range(1000)) साफ़ है; sum((n ** 2 for n in range(1000))) सही है पर भारी। दूसरे argument के साथ brackets ज़रूरी हैं: sorted((n % 7 for n in nums), reverse=True)।

当生成器表达式是函数的 唯一 参数时,可以省去它自己的括号:sum(n ** 2 for n in range(1000)) 很简洁;sum((n ** 2 for n in range(1000))) 合法但累赘。有第二个参数时必须加括号:sorted((n % 7 for n in nums), reverse=True)。


SectionSection第 12 节

Scope — What Stays Inside, and the Walrus Exception 🔒Scope — क्या अंदर रहता है, और Walrus का अपवाद 🔒作用域 — 什么留在里面,以及海象运算符的例外 🔒

The loop variable of a comprehension belongs to the comprehension. It does not overwrite a variable with the same name outside. There is one deliberate exception: a name assigned with the walrus operator := (Python 3.8+) is stored in the surrounding scope.

Comprehension का loop variable comprehension का ही होता है। यह बाहर के उसी नाम वाले variable को overwrite नहीं करता। एक जान-बूझकर अपवाद है: walrus operator := (Python 3.8+) से दिया गया नाम आसपास के scope में रखा जाता है।

推导式的循环变量属于推导式本身,不会覆盖外部同名变量。有一个有意设计的例外:用海象运算符 :=(Python 3.8+)赋值的名字会保存在外层作用域中。

n = "outer"
squares = [n * n for n in range(4)]
print(n)                        # the loop variable did not leak

# The walrus operator := is the one exception: it DOES leak
data = [3, 8, 12, 5]
big = [y for x in data if (y := x * 10) > 50]
print(big, y)                   # y is visible outside
OUTPUT
outer [80, 120] 50

The walrus here computes x * 10 once and uses it twice — in the filter and in the output. Handy, but use it sparingly; it makes a comprehension harder to read.

यहाँ walrus x * 10 एक बार गिनकर दो बार इस्तेमाल करता है — filter में और output में। काम का है, पर कम इस्तेमाल करें; इससे comprehension पढ़ना मुश्किल होता है।

这里海象运算符只计算一次 x * 10,却用了两次 — 在过滤条件和输出中。很方便,但要少用;它会让推导式更难读。


SectionSection第 13 节

When NOT to Use a Comprehension 🚫Comprehension कब इस्तेमाल न करें 🚫什么时候不该用推导式 🚫

Comprehensions are powerful, but they do not replace every loop. Use a plain for loop when the logic no longer fits comfortably in one expression.

Comprehensions ताक़तवर हैं, पर हर loop की जगह नहीं लेतीं। जब logic एक expression में आराम से न समाए, तो सामान्य for loop इस्तेमाल करें।

推导式很强大,但不能取代所有循环。当逻辑无法舒适地放进一个表达式时,就用普通 for 循环。

🚫
Side EffectsSide Effects副作用
log, save, print, change thingslog, save, print, चीज़ें बदलना记录、保存、打印、修改
Comprehensions should produce data, not do things. If each turn writes a file, calls an API or prints, use a for loop.
Comprehensions को data बनाना चाहिए, काम नहीं करना। अगर हर चक्कर file लिखे, API बुलाए या print करे, तो for loop इस्तेमाल करें।
推导式应该 产出数据,而不是做事。如果每一轮都要写文件、调 API 或打印,就用 for 循环。
🧠
Multi-Step Logicकई कदमों वाला Logic多步骤逻辑
try/except, break, many statements
You cannot put try/except, several statements or break inside a comprehension. When you need any of them, a loop is not just cleaner — it is the only option.
Comprehension के अंदर try/except, कई statements या break नहीं रख सकते। जब इनमें से कुछ भी चाहिए, तो loop सिर्फ़ साफ़ नहीं — इकलौता रास्ता है।
推导式里不能放 try/except、多条语句或 break。需要其中任何一个时,循环不只是更清晰 — 而是唯一的选择。
👀
Fails the Squint Testझट से न समझ आए一眼看不懂
takes more than a few seconds to readपढ़ने में कुछ सेकंड से ज़्यादा要读好几秒
If a colleague cannot read your comprehension at a glance, it is too clever. Short, focused comprehensions beat one "impressive" three-line monster.
अगर कोई साथी आपकी comprehension एक नज़र में न पढ़ सके, तो वह ज़रूरत से ज़्यादा चालाक है। छोटी, केंद्रित comprehensions एक "शानदार" तीन-line के राक्षस से बेहतर हैं।
如果同事无法一眼读懂你的推导式,它就太"聪明"了。简短、聚焦的推导式胜过一个"炫技"的三行怪物。

Bad Idea — A Comprehension for Side Effectsबुरा विचार — Side Effects के लिए Comprehension坏主意 — 为副作用写推导式

users = ["aarav", "meera", "kabir"]

# DON'T DO THIS - building a throwaway list just to run print()
result = [print(user) for user in users]
print(result)                  # a list of None values, nobody needs it

# DO THIS instead
for user in users:
    print(user.title())
OUTPUT
aarav meera kabir [None, None, None] Aarav Meera Kabir
⚠️
The One-Line Testएक-Line की परीक्षा一行测试

A good comprehension fits on one line, or breaks naturally across 2–3 short lines. If yours wraps past that, or the reader has to count brackets to understand it, refactor. The whole point was clarity — lose that and you have lost the win.

अच्छी comprehension एक line में आती है, या स्वाभाविक रूप से 2–3 छोटी lines में बँटती है। अगर आपकी उससे आगे जाए, या पढ़ने वाले को समझने के लिए brackets गिनने पड़ें, तो refactor करें। मक़सद साफ़ता थी — वह खोई तो जीत भी गई।

好的推导式能写在一行内,或自然地拆成 2–3 个短行。如果超出这个长度,或者读者得数括号才能看懂,就重构。初衷就是清晰 — 失去了清晰,也就失去了优势。


SectionSection第 14 节

Comparison Table — All Four at a Glance 📋तुलना Table — चारों एक नज़र में 📋对比表 — 四种一览 📋

Featureविशेषता特性ListDictSetGenerator
SyntaxSyntax语法[expr for x in it]{k: v for x in it}{expr for x in it}(expr for x in it)
Returnsलौटाता है返回listdictsetgenerator
Orderक्रम顺序Keptबना रहता है保持Insertion order (3.7+)डालने का क्रम (3.7+)插入顺序(3.7+)No fixed orderकोई तय क्रम नहीं无固定顺序Same as the sourceSource जैसा与源相同
DuplicatesDuplicates重复Allowedइजाज़त है允许Keys unique (last wins)Keys अनोखी (आख़िरी जीतती है)键唯一(后者胜出)Removedहटा दिए जाते हैं自动去除Allowedइजाज़त है允许
Element ruleElement का नियम元素要求Anythingकुछ भी任意Keys must be hashableKeys hashable हों键必须可哈希Must be hashableHashable हों必须可哈希Anythingकुछ भी任意
MemoryMemory内存All itemsसारे items全部元素All pairsसारी जोड़ियाँ全部键值对All unique itemsसारे अनोखे items全部唯一元素One at a timeएक बार में एक一次一个
Best forकिसके लिए适合General lists, transformsआम lists, बदलाव通用列表、转换Lookups, mappings, invertingLookups, mappings, उलटना查找表、映射、反转Deduplication, membership testsDuplicates हटाना, membership जाँच去重、成员检测Big data, one passबड़ा data, एक बार大数据、单次遍历

SectionSection第 15 节

Golden Rules and Quick Quiz 🏆सुनहरे नियम और छोटा Quiz 🏆黄金法则与小测验 🏆

🔑 Comprehensions — Rules to RememberComprehensions — याद रखने वाले नियम推导式 — 必须记住的规则
1
If you can read it aloud as one sentence, keep it as a comprehension. If you can't, turn it into a for loop. Clarity is the whole reason comprehensions exist.
अगर आप इसे एक वाक्य की तरह बोल सकें, तो comprehension रहने दें। न बोल सकें, तो for loop बना दें। Comprehensions की वजह ही साफ़ता है।
如果能像一句话一样读出来,就保留推导式。读不出来,就改成 for 循环。推导式存在的全部理由就是清晰。
2
A filter if goes at the end; an if … else transform goes at the front. The filter drops items; the transform changes them.
Filter वाला if अंत में; if … else transform आगे। Filter items हटाता है; transform उन्हें बदलता है।
过滤用的 if 放末尾;if … else 转换放前面。过滤丢弃元素,转换改变元素。
3
Never use a comprehension just for side effects — no print, file writes or API calls. If you don't keep the result, use a loop.
सिर्फ़ side effects के लिए comprehension कभी इस्तेमाल न करें — न print, न file writes, न API calls। अगर नतीजा नहीं रखते, तो loop इस्तेमाल करें।
永远不要只为副作用使用推导式 — 不要 print、写文件或调 API。如果不保留结果,就用循环。
4
Two fors is the ceiling. The first for is the outer loop. Beyond two levels, use a helper function or plain loops.
दो for ही छत है। पहला for बाहरी loop है। दो स्तरों से आगे helper function या सामान्य loops इस्तेमाल करें।
两个 for 是上限。第一个 for 是外层循环。超过两层就用辅助函数或普通循环。
5
For huge data, use a generator expression — round brackets. It produces one value at a time and works perfectly with sum(), max(), any(). Remember: it can be used only once.
बहुत बड़े data के लिए generator expression इस्तेमाल करें — गोल brackets। यह एक बार में एक value बनाता है और sum(), max(), any() के साथ बढ़िया चलता है। याद रखें: इसे सिर्फ़ एक बार इस्तेमाल कर सकते हैं।
处理超大数据用生成器表达式 — 圆括号。它一次产生一个值,与 sum()、max()、any() 完美配合。记住:它只能用一次。
6
A dict comprehension has exactly one colon — between key and value. Leave it out and you get a set comprehension; write {k, v for …} and you get a SyntaxError.
Dict comprehension में ठीक एक colon होता है — key और value के बीच। इसे छोड़ें तो set comprehension मिलती है; {k, v for …} लिखें तो SyntaxError।
字典推导式恰好有一个冒号 — 位于键和值之间。省掉它就成了集合推导式;写成 {k, v for …} 则得到 SyntaxError。
7
When keys can repeat, the last one wins silently. Check before inverting a dict, or group values into lists.
जब keys दोहरा सकती हों, आख़िरी चुपचाप जीतती है। Dict उलटने से पहले जाँचें, या values को lists में समूह बनाएँ।
键可能重复时,最后一个会悄悄胜出。反转字典前先检查,或把值分组成列表。
8
Never rely on set order. Use sorted() when you need a stable order.
Set के क्रम पर कभी भरोसा न करें। स्थिर क्रम चाहिए तो sorted() इस्तेमाल करें।
永远不要依赖集合的顺序。需要稳定顺序时用 sorted()。
9
Comprehensions have their own scope. The loop variable does not leak — but a name set with := does.
Comprehensions का अपना scope होता है। Loop variable बाहर नहीं रिसता — पर := से दिया गया नाम रिसता है।
推导式有自己的作用域。循环变量不会泄漏 — 但用 := 赋值的名字会。

Quick Quiz — 8 Questionsछोटा Quiz — 8 सवाल小测验 — 8 道题

🏆 QuizPick an answer to see why.जवाब चुनें और कारण देखें।选一个答案,看看原因。
🎯
Key Takeawayमुख्य सीख关键要点

A comprehension is a for loop turned into a description: output, for, optional if, wrapped in the brackets of the container you want. Put filters at the end and transforms at the front, keep it to two fors, switch to round brackets for big data, and fall back to a plain loop whenever clarity suffers.

Comprehension एक for loop है जिसे वर्णन में बदला गया: output, for, वैकल्पिक if, और चाहे गए container के brackets। Filters अंत में और transforms आगे रखें, दो for तक सीमित रहें, बड़े data के लिए गोल brackets लें, और जब भी साफ़ता घटे, सामान्य loop पर लौट आएँ।

推导式就是把 for 循环变成一句描述:输出、for、可选的 if,再套上你想要的容器的括号。过滤放末尾,转换放前面,最多两个 for,大数据换成圆括号;一旦清晰度受损,就回到普通循环。

🐍 Try Python Yourself

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

You have completed Comprehensions. View all sections →