[{"data":1,"prerenderedAt":1209},["ShallowReactive",2],{"blog-\u002Fblog\u002Fpython-generators-vs-iterators-vs-comprehensions":3},{"id":4,"title":5,"body":6,"description":1196,"difficulty":1197,"extension":1198,"framework":1199,"frameworkSlug":217,"meta":1200,"navigation":364,"order":297,"path":1201,"qaPath":666,"seo":1202,"stem":1203,"subtopic":1204,"topic":1205,"topicSlug":1206,"updated":1207,"__hash__":1208},"blog\u002Fblog\u002Fpython-generators-vs-iterators-vs-comprehensions.md","Python Generators vs Iterators vs Comprehensions — Choosing the Right Tool",{"type":7,"value":8,"toc":1186},"minimark",[9,14,31,35,194,198,212,306,309,322,325,336,340,347,499,506,555,567,646,649,660,668,672,691,891,898,1006,1009,1031,1039,1043,1051,1055,1071,1149,1160,1164,1182],[10,11,13],"h2",{"id":12},"three-tools-for-the-same-job-but-not-interchangeable","Three tools for the same job — but not interchangeable",[15,16,17,18,22,23,26,27,30],"p",{},"Every Python developer uses list comprehensions daily, reaches for generators when memory\nis tight, and writes custom iterators when building reusable data sources. But the\ndifferences between them go deeper than syntax — they have fundamentally different\n",[19,20,21],"strong",{},"memory behaviour",", ",[19,24,25],{},"laziness",", and ",[19,28,29],{},"reusability"," that determine which is right for\nany given situation.",[10,32,34],{"id":33},"quick-reference-comparison","Quick-reference comparison",[36,37,38,56],"table",{},[39,40,41],"thead",{},[42,43,44,47,50,53],"tr",{},[45,46],"th",{},[45,48,49],{},"List comprehension",[45,51,52],{},"Generator expression",[45,54,55],{},"Custom iterator (class)",[57,58,59,88,103,119,142,160,178],"tbody",{},[42,60,61,67,73,78],{},[62,63,64],"td",{},[19,65,66],{},"Syntax",[62,68,69],{},[70,71,72],"code",{},"[x for x in it]",[62,74,75],{},[70,76,77],{},"(x for x in it)",[62,79,80,81,84,85],{},"class with ",[70,82,83],{},"__iter__"," + ",[70,86,87],{},"__next__",[42,89,90,95,98,101],{},[62,91,92],{},[19,93,94],{},"Evaluation",[62,96,97],{},"Eager — builds all at once",[62,99,100],{},"Lazy — one item at a time",[62,102,100],{},[42,104,105,110,113,116],{},[62,106,107],{},[19,108,109],{},"Memory",[62,111,112],{},"O(n) — holds all items",[62,114,115],{},"O(1) — one item at a time",[62,117,118],{},"O(1) typically",[42,120,121,126,129,132],{},[62,122,123],{},[19,124,125],{},"Iterable again?",[62,127,128],{},"Yes — a list, reuse freely",[62,130,131],{},"No — exhausted after one pass",[62,133,134,135,137,138,141],{},"Yes (if ",[70,136,83],{}," returns ",[70,139,140],{},"self",")",[42,143,144,149,155,158],{},[62,145,146],{},[19,147,148],{},"Indexable?",[62,150,151,152,141],{},"Yes (",[70,153,154],{},"result[0]",[62,156,157],{},"No",[62,159,157],{},[42,161,162,170,173,175],{},[62,163,164],{},[19,165,166,169],{},[70,167,168],{},"len()","?",[62,171,172],{},"Yes",[62,174,157],{},[62,176,177],{},"No (unless you implement it)",[42,179,180,185,188,191],{},[62,181,182],{},[19,183,184],{},"Best for",[62,186,187],{},"Short sequences you'll reuse",[62,189,190],{},"Large \u002F infinite \u002F pipeline data",[62,192,193],{},"Stateful, reusable data sources",[10,195,197],{"id":196},"list-comprehensions-eager-indexed-reusable","List comprehensions — eager, indexed, reusable",[15,199,200,201,204,205,208,209,211],{},"A list comprehension builds the ",[19,202,203],{},"entire result in memory at once"," and returns a plain\n",[70,206,207],{},"list",". Because it's a real list, you can index it, call ",[70,210,168],{},", iterate it multiple\ntimes, sort it, or pass it to any function expecting a sequence.",[213,214,219],"pre",{"className":215,"code":216,"language":217,"meta":218,"style":218},"language-python shiki shiki-themes github-light github-dark","squares = [n * n for n in range(10)]   # built immediately — all 10 values in RAM\nsquares[0]          # 0   — indexable\nlen(squares)        # 10  — knows its size\nlist(squares)       # [0, 1, 4, ...] — can iterate again\n","python","",[70,220,221,268,283,295],{"__ignoreMap":218},[222,223,226,230,234,237,240,243,246,248,251,255,258,261,264],"span",{"class":224,"line":225},"line",1,[222,227,229],{"class":228},"sVt8B","squares ",[222,231,233],{"class":232},"szBVR","=",[222,235,236],{"class":228}," [n ",[222,238,239],{"class":232},"*",[222,241,242],{"class":228}," n ",[222,244,245],{"class":232},"for",[222,247,242],{"class":228},[222,249,250],{"class":232},"in",[222,252,254],{"class":253},"sj4cs"," range",[222,256,257],{"class":228},"(",[222,259,260],{"class":253},"10",[222,262,263],{"class":228},")]   ",[222,265,267],{"class":266},"sJ8bj","# built immediately — all 10 values in RAM\n",[222,269,271,274,277,280],{"class":224,"line":270},2,[222,272,273],{"class":228},"squares[",[222,275,276],{"class":253},"0",[222,278,279],{"class":228},"]          ",[222,281,282],{"class":266},"# 0   — indexable\n",[222,284,286,289,292],{"class":224,"line":285},3,[222,287,288],{"class":253},"len",[222,290,291],{"class":228},"(squares)        ",[222,293,294],{"class":266},"# 10  — knows its size\n",[222,296,298,300,303],{"class":224,"line":297},4,[222,299,207],{"class":253},[222,301,302],{"class":228},"(squares)       ",[222,304,305],{"class":266},"# [0, 1, 4, ...] — can iterate again\n",[15,307,308],{},"Use a list comprehension when:",[310,311,312,316,319],"ul",{},[313,314,315],"li",{},"The result is small enough to hold in memory.",[313,317,318],{},"You need to index, sort, or inspect the result multiple times.",[313,320,321],{},"You're transforming one sequence into another in a single step.",[15,323,324],{},"The trade-off: for large data sets, storing every element wastes memory. A list of one\nmillion integers takes ~8 MB; the equivalent generator takes ~100 bytes.",[326,327,328],"blockquote",{},[15,329,330,331],{},"Deep dive: ",[332,333,335],"a",{"href":334},"\u002Fpython\u002Fiteration\u002Fcomprehensions","Comprehensions interview questions",[10,337,339],{"id":338},"generator-expressions-lazy-one-pass-memory-efficient","Generator expressions — lazy, one-pass, memory efficient",[15,341,342,343,346],{},"Change the brackets to parentheses and the comprehension becomes a ",[19,344,345],{},"generator\nexpression",": lazy, one-element-at-a-time, with a tiny fixed memory footprint. It doesn't\ncompute anything until you iterate it.",[213,348,350],{"className":215,"code":349,"language":217,"meta":218,"style":218},"import sys\n\nnums_list = [n * n for n in range(1_000_000)]   # ~8 MB — built now\nnums_gen  = (n * n for n in range(1_000_000))   # ~100 bytes — nothing built yet\n\nsys.getsizeof(nums_list)    # large\nsys.getsizeof(nums_gen)     # tiny, regardless of range size\n\n# Use just like a list in a for loop or sum\u002Fmax\u002Fany\u002Fall:\ntotal = sum(n * n for n in range(1_000_000))    # streams, never builds the list\n",[70,351,352,360,366,397,429,434,443,452,457,463],{"__ignoreMap":218},[222,353,354,357],{"class":224,"line":225},[222,355,356],{"class":232},"import",[222,358,359],{"class":228}," sys\n",[222,361,362],{"class":224,"line":270},[222,363,365],{"emptyLinePlaceholder":364},true,"\n",[222,367,368,371,373,375,377,379,381,383,385,387,389,392,394],{"class":224,"line":285},[222,369,370],{"class":228},"nums_list ",[222,372,233],{"class":232},[222,374,236],{"class":228},[222,376,239],{"class":232},[222,378,242],{"class":228},[222,380,245],{"class":232},[222,382,242],{"class":228},[222,384,250],{"class":232},[222,386,254],{"class":253},[222,388,257],{"class":228},[222,390,391],{"class":253},"1_000_000",[222,393,263],{"class":228},[222,395,396],{"class":266},"# ~8 MB — built now\n",[222,398,399,402,404,407,409,411,413,415,417,419,421,423,426],{"class":224,"line":297},[222,400,401],{"class":228},"nums_gen  ",[222,403,233],{"class":232},[222,405,406],{"class":228}," (n ",[222,408,239],{"class":232},[222,410,242],{"class":228},[222,412,245],{"class":232},[222,414,242],{"class":228},[222,416,250],{"class":232},[222,418,254],{"class":253},[222,420,257],{"class":228},[222,422,391],{"class":253},[222,424,425],{"class":228},"))   ",[222,427,428],{"class":266},"# ~100 bytes — nothing built yet\n",[222,430,432],{"class":224,"line":431},5,[222,433,365],{"emptyLinePlaceholder":364},[222,435,437,440],{"class":224,"line":436},6,[222,438,439],{"class":228},"sys.getsizeof(nums_list)    ",[222,441,442],{"class":266},"# large\n",[222,444,446,449],{"class":224,"line":445},7,[222,447,448],{"class":228},"sys.getsizeof(nums_gen)     ",[222,450,451],{"class":266},"# tiny, regardless of range size\n",[222,453,455],{"class":224,"line":454},8,[222,456,365],{"emptyLinePlaceholder":364},[222,458,460],{"class":224,"line":459},9,[222,461,462],{"class":266},"# Use just like a list in a for loop or sum\u002Fmax\u002Fany\u002Fall:\n",[222,464,466,469,471,474,477,479,481,483,485,487,489,491,493,496],{"class":224,"line":465},10,[222,467,468],{"class":228},"total ",[222,470,233],{"class":232},[222,472,473],{"class":253}," sum",[222,475,476],{"class":228},"(n ",[222,478,239],{"class":232},[222,480,242],{"class":228},[222,482,245],{"class":232},[222,484,242],{"class":228},[222,486,250],{"class":232},[222,488,254],{"class":253},[222,490,257],{"class":228},[222,492,391],{"class":253},[222,494,495],{"class":228},"))    ",[222,497,498],{"class":266},"# streams, never builds the list\n",[15,500,501,502,505],{},"The critical limitation: a generator is ",[19,503,504],{},"exhausted after one pass",". Iterating it a\nsecond time yields nothing:",[213,507,509],{"className":215,"code":508,"language":217,"meta":218,"style":218},"gen = (n for n in range(3))\nlist(gen)    # [0, 1, 2]\nlist(gen)    # []  — exhausted; create a new generator if you need to re-iterate\n",[70,510,511,536,546],{"__ignoreMap":218},[222,512,513,516,518,520,522,524,526,528,530,533],{"class":224,"line":225},[222,514,515],{"class":228},"gen ",[222,517,233],{"class":232},[222,519,406],{"class":228},[222,521,245],{"class":232},[222,523,242],{"class":228},[222,525,250],{"class":232},[222,527,254],{"class":253},[222,529,257],{"class":228},[222,531,532],{"class":253},"3",[222,534,535],{"class":228},"))\n",[222,537,538,540,543],{"class":224,"line":270},[222,539,207],{"class":253},[222,541,542],{"class":228},"(gen)    ",[222,544,545],{"class":266},"# [0, 1, 2]\n",[222,547,548,550,552],{"class":224,"line":285},[222,549,207],{"class":253},[222,551,542],{"class":228},[222,553,554],{"class":266},"# []  — exhausted; create a new generator if you need to re-iterate\n",[15,556,557,558,562,563,566],{},"Generator ",[559,560,561],"em",{},"functions"," (using ",[70,564,565],{},"yield",") give you the same laziness with more control:",[213,568,570],{"className":215,"code":569,"language":217,"meta":218,"style":218},"def squares(n):\n    for i in range(n):\n        yield i * i    # pauses here between calls to next()\n\nfor s in squares(5):\n    print(s)           # 0, 1, 4, 9, 16 — computed one at a time\n",[70,571,572,584,598,613,617,635],{"__ignoreMap":218},[222,573,574,577,581],{"class":224,"line":225},[222,575,576],{"class":232},"def",[222,578,580],{"class":579},"sScJk"," squares",[222,582,583],{"class":228},"(n):\n",[222,585,586,589,592,594,596],{"class":224,"line":270},[222,587,588],{"class":232},"    for",[222,590,591],{"class":228}," i ",[222,593,250],{"class":232},[222,595,254],{"class":253},[222,597,583],{"class":228},[222,599,600,603,605,607,610],{"class":224,"line":285},[222,601,602],{"class":232},"        yield",[222,604,591],{"class":228},[222,606,239],{"class":232},[222,608,609],{"class":228}," i    ",[222,611,612],{"class":266},"# pauses here between calls to next()\n",[222,614,615],{"class":224,"line":297},[222,616,365],{"emptyLinePlaceholder":364},[222,618,619,621,624,626,629,632],{"class":224,"line":431},[222,620,245],{"class":232},[222,622,623],{"class":228}," s ",[222,625,250],{"class":232},[222,627,628],{"class":228}," squares(",[222,630,631],{"class":253},"5",[222,633,634],{"class":228},"):\n",[222,636,637,640,643],{"class":224,"line":436},[222,638,639],{"class":253},"    print",[222,641,642],{"class":228},"(s)           ",[222,644,645],{"class":266},"# 0, 1, 4, 9, 16 — computed one at a time\n",[15,647,648],{},"Use a generator when:",[310,650,651,654,657],{},[313,652,653],{},"The data set is large or potentially infinite.",[313,655,656],{},"You're building a pipeline (transforming → filtering → consuming without staging all at once).",[313,658,659],{},"You only need to iterate once.",[326,661,662],{},[15,663,330,664],{},[332,665,667],{"href":666},"\u002Fpython\u002Fiteration\u002Fgenerators","Generators & yield interview questions",[10,669,671],{"id":670},"custom-iterators-stateful-reusable-flexible","Custom iterators — stateful, reusable, flexible",[15,673,674,675,678,679,681,682,26,684,686,687,690],{},"A custom iterator is a class that implements the ",[19,676,677],{},"iterator protocol",": ",[70,680,83],{}," returns\n",[70,683,140],{},[70,685,87],{}," returns the next value or raises ",[70,688,689],{},"StopIteration",". This approach is\nmore verbose than a generator but gives you full control over state, restartability, and\nadditional methods.",[213,692,694],{"className":215,"code":693,"language":217,"meta":218,"style":218},"class Counter:\n    def __init__(self, start, stop):\n        self.current = start\n        self.stop = stop\n\n    def __iter__(self):\n        return self         # the iterator is its own iterable\n\n    def __next__(self):\n        if self.current >= self.stop:\n            raise StopIteration\n        value = self.current\n        self.current += 1\n        return value\n\nc = Counter(1, 4)\nlist(c)    # [1, 2, 3]\n# Note: c is now exhausted — Counter.__iter__ returns self, not a reset copy\n# Reset by creating a new Counter(1, 4)\n",[70,695,696,707,718,731,743,747,757,768,772,781,798,807,820,833,841,846,868,879,885],{"__ignoreMap":218},[222,697,698,701,704],{"class":224,"line":225},[222,699,700],{"class":232},"class",[222,702,703],{"class":579}," Counter",[222,705,706],{"class":228},":\n",[222,708,709,712,715],{"class":224,"line":270},[222,710,711],{"class":232},"    def",[222,713,714],{"class":253}," __init__",[222,716,717],{"class":228},"(self, start, stop):\n",[222,719,720,723,726,728],{"class":224,"line":285},[222,721,722],{"class":253},"        self",[222,724,725],{"class":228},".current ",[222,727,233],{"class":232},[222,729,730],{"class":228}," start\n",[222,732,733,735,738,740],{"class":224,"line":297},[222,734,722],{"class":253},[222,736,737],{"class":228},".stop ",[222,739,233],{"class":232},[222,741,742],{"class":228}," stop\n",[222,744,745],{"class":224,"line":431},[222,746,365],{"emptyLinePlaceholder":364},[222,748,749,751,754],{"class":224,"line":436},[222,750,711],{"class":232},[222,752,753],{"class":253}," __iter__",[222,755,756],{"class":228},"(self):\n",[222,758,759,762,765],{"class":224,"line":445},[222,760,761],{"class":232},"        return",[222,763,764],{"class":253}," self",[222,766,767],{"class":266},"         # the iterator is its own iterable\n",[222,769,770],{"class":224,"line":454},[222,771,365],{"emptyLinePlaceholder":364},[222,773,774,776,779],{"class":224,"line":459},[222,775,711],{"class":232},[222,777,778],{"class":253}," __next__",[222,780,756],{"class":228},[222,782,783,786,788,790,793,795],{"class":224,"line":465},[222,784,785],{"class":232},"        if",[222,787,764],{"class":253},[222,789,725],{"class":228},[222,791,792],{"class":232},">=",[222,794,764],{"class":253},[222,796,797],{"class":228},".stop:\n",[222,799,801,804],{"class":224,"line":800},11,[222,802,803],{"class":232},"            raise",[222,805,806],{"class":253}," StopIteration\n",[222,808,810,813,815,817],{"class":224,"line":809},12,[222,811,812],{"class":228},"        value ",[222,814,233],{"class":232},[222,816,764],{"class":253},[222,818,819],{"class":228},".current\n",[222,821,823,825,827,830],{"class":224,"line":822},13,[222,824,722],{"class":253},[222,826,725],{"class":228},[222,828,829],{"class":232},"+=",[222,831,832],{"class":253}," 1\n",[222,834,836,838],{"class":224,"line":835},14,[222,837,761],{"class":232},[222,839,840],{"class":228}," value\n",[222,842,844],{"class":224,"line":843},15,[222,845,365],{"emptyLinePlaceholder":364},[222,847,849,852,854,857,860,862,865],{"class":224,"line":848},16,[222,850,851],{"class":228},"c ",[222,853,233],{"class":232},[222,855,856],{"class":228}," Counter(",[222,858,859],{"class":253},"1",[222,861,22],{"class":228},[222,863,864],{"class":253},"4",[222,866,867],{"class":228},")\n",[222,869,871,873,876],{"class":224,"line":870},17,[222,872,207],{"class":253},[222,874,875],{"class":228},"(c)    ",[222,877,878],{"class":266},"# [1, 2, 3]\n",[222,880,882],{"class":224,"line":881},18,[222,883,884],{"class":266},"# Note: c is now exhausted — Counter.__iter__ returns self, not a reset copy\n",[222,886,888],{"class":224,"line":887},19,[222,889,890],{"class":266},"# Reset by creating a new Counter(1, 4)\n",[15,892,893,894,897],{},"For a ",[19,895,896],{},"reusable"," iterable (re-iterate from the start each time), separate the iterable\nfrom the iterator:",[213,899,901],{"className":215,"code":900,"language":217,"meta":218,"style":218},"class NumberRange:\n    def __init__(self, start, stop):\n        self.start, self.stop = start, stop\n\n    def __iter__(self):\n        return Counter(self.start, self.stop)  # fresh iterator on each call\n\nr = NumberRange(1, 4)\nlist(r)    # [1, 2, 3]\nlist(r)    # [1, 2, 3] — works again\n",[70,902,903,912,920,936,940,948,966,970,988,997],{"__ignoreMap":218},[222,904,905,907,910],{"class":224,"line":225},[222,906,700],{"class":232},[222,908,909],{"class":579}," NumberRange",[222,911,706],{"class":228},[222,913,914,916,918],{"class":224,"line":270},[222,915,711],{"class":232},[222,917,714],{"class":253},[222,919,717],{"class":228},[222,921,922,924,927,929,931,933],{"class":224,"line":285},[222,923,722],{"class":253},[222,925,926],{"class":228},".start, ",[222,928,140],{"class":253},[222,930,737],{"class":228},[222,932,233],{"class":232},[222,934,935],{"class":228}," start, stop\n",[222,937,938],{"class":224,"line":297},[222,939,365],{"emptyLinePlaceholder":364},[222,941,942,944,946],{"class":224,"line":431},[222,943,711],{"class":232},[222,945,753],{"class":253},[222,947,756],{"class":228},[222,949,950,952,954,956,958,960,963],{"class":224,"line":436},[222,951,761],{"class":232},[222,953,856],{"class":228},[222,955,140],{"class":253},[222,957,926],{"class":228},[222,959,140],{"class":253},[222,961,962],{"class":228},".stop)  ",[222,964,965],{"class":266},"# fresh iterator on each call\n",[222,967,968],{"class":224,"line":445},[222,969,365],{"emptyLinePlaceholder":364},[222,971,972,975,977,980,982,984,986],{"class":224,"line":454},[222,973,974],{"class":228},"r ",[222,976,233],{"class":232},[222,978,979],{"class":228}," NumberRange(",[222,981,859],{"class":253},[222,983,22],{"class":228},[222,985,864],{"class":253},[222,987,867],{"class":228},[222,989,990,992,995],{"class":224,"line":459},[222,991,207],{"class":253},[222,993,994],{"class":228},"(r)    ",[222,996,878],{"class":266},[222,998,999,1001,1003],{"class":224,"line":465},[222,1000,207],{"class":253},[222,1002,994],{"class":228},[222,1004,1005],{"class":266},"# [1, 2, 3] — works again\n",[15,1007,1008],{},"Use a custom iterator class when:",[310,1010,1011,1021,1024],{},[313,1012,1013,1014,22,1017,1020],{},"The data source has complex state that benefits from methods (",[70,1015,1016],{},"reset()",[70,1018,1019],{},"peek()",").",[313,1022,1023],{},"You want the same iterable to be re-iterable (separate iterable from iterator).",[313,1025,1026,1027,1030],{},"You're integrating with a resource (file, socket, DB cursor) that requires cleanup in ",[70,1028,1029],{},"__del__",".",[326,1032,1033],{},[15,1034,330,1035],{},[332,1036,1038],{"href":1037},"\u002Fpython\u002Fiteration\u002Fiterators","Iterators & the Iterator Protocol interview questions",[10,1040,1042],{"id":1041},"the-decision-flowchart","The decision flowchart",[213,1044,1049],{"className":1045,"code":1047,"language":1048},[1046],"language-text","Is the result small and will you use it multiple times (index, sort, len)?\n└── Yes → list comprehension\n\nIs the data large, infinite, or a processing pipeline you'll consume once?\n└── Yes → generator expression or generator function (yield)\n\nDo you need a reusable data source with state or multiple methods?\n└── Yes → custom iterator class\n","text",[70,1050,1047],{"__ignoreMap":218},[10,1052,1054],{"id":1053},"when-generators-beat-comprehensions-even-for-small-data","When generators beat comprehensions even for small data",[15,1056,1057,1058,22,1061,22,1064,26,1067,1070],{},"Even for small data, generators win inside ",[70,1059,1060],{},"sum()",[70,1062,1063],{},"max()",[70,1065,1066],{},"any()",[70,1068,1069],{},"all()"," because\nthose functions consume the iterable in a single pass and don't need the list. Passing a\ngenerator expression avoids the intermediate allocation:",[213,1072,1074],{"className":215,"code":1073,"language":217,"meta":218,"style":218},"# unnecessary list — builds it, then sums it, then discards it\ntotal = sum([n * n for n in range(1000)])\n\n# better — streams directly into sum(), no list ever built\ntotal = sum(n * n for n in range(1000))\n",[70,1075,1076,1081,1112,1116,1121],{"__ignoreMap":218},[222,1077,1078],{"class":224,"line":225},[222,1079,1080],{"class":266},"# unnecessary list — builds it, then sums it, then discards it\n",[222,1082,1083,1085,1087,1089,1092,1094,1096,1098,1100,1102,1104,1106,1109],{"class":224,"line":270},[222,1084,468],{"class":228},[222,1086,233],{"class":232},[222,1088,473],{"class":253},[222,1090,1091],{"class":228},"([n ",[222,1093,239],{"class":232},[222,1095,242],{"class":228},[222,1097,245],{"class":232},[222,1099,242],{"class":228},[222,1101,250],{"class":232},[222,1103,254],{"class":253},[222,1105,257],{"class":228},[222,1107,1108],{"class":253},"1000",[222,1110,1111],{"class":228},")])\n",[222,1113,1114],{"class":224,"line":285},[222,1115,365],{"emptyLinePlaceholder":364},[222,1117,1118],{"class":224,"line":297},[222,1119,1120],{"class":266},"# better — streams directly into sum(), no list ever built\n",[222,1122,1123,1125,1127,1129,1131,1133,1135,1137,1139,1141,1143,1145,1147],{"class":224,"line":431},[222,1124,468],{"class":228},[222,1126,233],{"class":232},[222,1128,473],{"class":253},[222,1130,476],{"class":228},[222,1132,239],{"class":232},[222,1134,242],{"class":228},[222,1136,245],{"class":232},[222,1138,242],{"class":228},[222,1140,250],{"class":232},[222,1142,254],{"class":253},[222,1144,257],{"class":228},[222,1146,1108],{"class":253},[222,1148,535],{"class":228},[15,1150,1151,1152,1155,1156,1159],{},"The outer ",[70,1153,1154],{},"()"," from ",[70,1157,1158],{},"sum(...)"," acts as the generator's delimiters — no extra parentheses\nneeded.",[10,1161,1163],{"id":1162},"recap","Recap",[15,1165,1166,1167,1170,1171,1174,1175,1177,1178,1181],{},"A ",[19,1168,1169],{},"list comprehension"," is eager, O(n) memory, indexable, and re-iterable — use it when\nthe result fits in memory and you need a real list. A ",[19,1172,1173],{},"generator expression"," (or\n",[70,1176,565],{},"-based generator function) is lazy, O(1) memory, and one-pass — use it for large\ndata, infinite sequences, or pipelines. A ",[19,1179,1180],{},"custom iterator class"," is lazy, stateful, and\nflexible — use it when you need reusability, complex state, or resource management that\ngoes beyond what a generator can express cleanly.",[1183,1184,1185],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":218,"searchDepth":270,"depth":270,"links":1187},[1188,1189,1190,1191,1192,1193,1194,1195],{"id":12,"depth":270,"text":13},{"id":33,"depth":270,"text":34},{"id":196,"depth":270,"text":197},{"id":338,"depth":270,"text":339},{"id":670,"depth":270,"text":671},{"id":1041,"depth":270,"text":1042},{"id":1053,"depth":270,"text":1054},{"id":1162,"depth":270,"text":1163},"Python generators vs iterators vs list comprehensions — memory footprint, laziness, reusability, and the decision rule for picking the right iteration tool in interviews and production code.","medium","md","Python",{},"\u002Fblog\u002Fpython-generators-vs-iterators-vs-comprehensions",{"title":5,"description":1196},"blog\u002Fpython-generators-vs-iterators-vs-comprehensions","Generators vs Iterators vs Comprehensions","Comprehensions & Iteration","iteration","2026-06-21","px3MDthhpz3Tu45Fb77Fp9Xn4ep621NiL1vyKk4_j4Q",1782244087880]