PageSourceSearch

https://cics110.github.io/assets/js/a525f614.58e48998.js

js cics110.github.io collected 2026-10-03 08:49:26 UTC 32,129 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5402],{3905:(e,n,t)=>{t.d(n,{Zo:()=>m,kt:()=>d});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?r(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):r(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,a,i=function(e,n){if(null==e)return{};var t,a,i={},r=Object.keys(e);for(a=0;a<r.length;a++)t=r[a],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)t=r[a],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=a.createContext({}),p=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},m=function(e){var n=p(e.components);return a.createElement(l.Provider,{value:n},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=p(t),h=i,d=c["".concat(l,".").concat(h)]||c[h]||u[h]||r;return t?a.createElement(d,s(s({ref:n},m),{},{components:t})):a.createElement(d,s({ref:n},m))}));function d(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,s=new Array(r);s[0]=h;var o={};for(var l in n)hasOwnProperty.call(n,l)&&(o[l]=n[l]);o.originalType=e,o[c]="string"==typeof e?e:i,s[1]=o;for(var p=2;p<r;p++)s[p]=t[p];return a.createElement.apply(null,s)}return a.createElement.apply(null,t)}h.displayName="MDXCreateElement"},81442:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>r,metadata:()=>o,toc:()=>p});var a=t(87462),i=(t(67294),t(3905));const r={title:"Section 04 (Jared Yeager)"},s="Ternary Operator and Comprehensions",o={unversionedId:"looping-patterns/Jared/index",id:"looping-patterns/Jared/index",title:"Section 04 (Jared Yeager)",description:"This lecture is pure syntax sugar. Not a thing here will be necessary.",source:"@site/main/lectures/12-looping-patterns/Jared/index.md",sourceDirName:"12-looping-patterns/Jared",slug:"/looping-patterns/Jared/",permalink:"/main/lectures/looping-patterns/Jared/",draft:!1,tags:[],version:"current",frontMatter:{title:"Section 04 (Jared Yeager)"},sidebar:"tutorialSidebar",previous:{title:"Lec 12 Looping Patterns",permalink:"/main/lectures/looping-patterns/"},next:{title:"Lec 13 Errors and Modules",permalink:"/main/lectures/errors_modules_docs/"}},l={},p=[{value:"Syntax Sugar",id:"syntax-sugar",level:3},{value:"Ternary Operators",id:"ternary-operators",level:2},{value:"Setting: Conditional Assignment",id:"setting-conditional-assignment",level:3},{value:"Syntax Sugar: Ternary Operator",id:"syntax-sugar-ternary-operator",level:3},{value:"Mapping and Comprehensions",id:"mapping-and-comprehensions",level:2},{value:"Setting: Mapping",id:"setting-mapping",level:3},{value:"Syntax Sugar: Comprehensions",id:"syntax-sugar-comprehensions",level:3},{value:"Filtering and Comprehensions",id:"filtering-and-comprehensions",level:2},{value:"Setting: Filtering",id:"setting-filtering",level:3},{value:"Syntax Sugar: More Comprehensions",id:"syntax-sugar-more-comprehensions",level:3},{value:"More Comprehension Types",id:"more-comprehension-types",level:2},{value:"Chaining",id:"chaining",level:2},{value:"Ternary Operators",id:"ternary-operators-1",level:3},{value:"Comprehensions",id:"comprehensions",level:3},{value:"Apotheosis (More Exotic Examples)",id:"apotheosis-more-exotic-examples",level:2}],m={toc:p};
1function c(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"ternary-operator-and-comprehensions"},"Ternary Operator and Comprehensions"),(0,i.kt)("p",null,"This lecture is ",(0,i.kt)("strong",{parentName:"p"},"pure syntax sugar"),". Not a thing here will be necessary.\nNot a thing here will be tested on a programming assignment\n(I'm not crawling your abstract syntax trees to figure out ",(0,i.kt)("strong",{parentName:"p"},"how")," you solved something).\nComprehensions don't even exist outside of Python.\nAnd yet, these things can be incredibly useful and powerful tools in the arsenal\nonce the fundamentals are cemented."),(0,i.kt)("h3",{id:"syntax-sugar"},"Syntax Sugar"),(0,i.kt)("p",null,"What is ",(0,i.kt)("em",{parentName:"p"},"syntax sugar"),'?\nSyntax sugar is my crippling addiction.\nIt is syntax that allows you to express certain common tasks in a denser/more concise form.\nSufficient mastery of syntax sugar can allow one to convert some tasks from a multi-line\nnested looping/branching statement, to a one-line eldritch monstrosity.\nDoing this gives me a kind of rush that I can\'t describe and continually crave.\nIt has made me what some would call a "degenerate", a "monster", or a "psychopath".\nBut I don\'t care. There is beauty in the horror.'),(0,i.kt)("h2",{id:"ternary-operators"},"Ternary Operators"),(0,i.kt)("h3",{id:"setting-conditional-assignment"},"Setting: Conditional Assignment"),(0,i.kt)("p",null,"There are cases where you want to set a value based on a condition."),(0,i.kt)("p",null,'A basic mathematical example is the "indicator function",\nwhich takes in a set ',(0,i.kt)("span",{parentName:"p",className:"math math-inline"},(0,i.kt)("span",{parentName:"span",className:"katex"},(0,i.kt)("span",{parentName:"span",className:"katex-mathml"},(0,i.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,i.kt)("semantics",{parentName:"math"},(0,i.kt)("mrow",{parentName:"semantics"},(0,i.kt)("mi",{parentName:"mrow"},"A")),(0,i.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"A")))),(0,i.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,i.kt)("span",{parentName:"span",className:"base"},(0,i.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,i.kt)("span",{parentName:"span",className:"mord mathnormal"},"A")))))," and an element ",(0,i.kt)("span",{parentName:"p",className:"math math-inline"},(0,i.kt)("span",{parentName:"span",className:"katex"},(0,i.kt)("span",{parentName:"span",className:"katex-mathml"},(0,i.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,i.kt)("semantics",{parentName:"math"},(0,i.kt)("mrow",{parentName:"semantics"},(0,i.kt)("mi",{parentName:"mrow"},"x")),(0,i.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"x")))),(0,i.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,i.kt)("span",{parentName:"span",className:"base"},(0,i.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,i.kt)("span",{parentName:"span",className:"mord mathnormal"},"x"))))),", and returns 1 if ",(0,i.kt)("span",{parentName:"p",className:"math math-inline"},(0,i.kt)("span",{parentName:"span",className:"katex"},(0,i.kt)("span",{parentName:"span",className:"katex-mathml"},(0,i.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,i.kt)("semantics",{parentName:"math"},(0,i.kt)("mrow",{parentName:"semantics"},(0,i.kt)("mi",{parentName:"mrow"},"x")),(0,i.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"x")))),(0,i.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,i.kt)("span",{parentName:"span",className:"base"},(0,i.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,i.kt)("span",{parentName:"span",className:"mord mathnormal"},"x")))))," is in ",(0,i.kt)("span",{parentName:"p",className:"math math-inline"},(0,i.kt)("span",{parentName:"span",className:"katex"},(0,i.kt)("span",{parentName:"span",className:"katex-mathml"},(0,i.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,i.kt)("semantics",{parentName:"math"},(0,i.kt)("mrow",{parentName:"semantics"},(0,i.kt)("mi",{parentName:"mrow"},"A")),(0,i.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"A")))),(0,i.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,i.kt)("span",{parentName:"span",className:"base"},(0,i.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,i.kt)("span",{parentName:"span",className:"mord mathnormal"},"A")))))," and 0 if not."),(0,i.kt)("p",null,"Just isolating the check and variable assignment (not making this into a python function),\nwe could accomplish the indicator checking like so:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Indicator",live_py:!0,title:"Indicator"},'A = {1,2,3,4,5}\nx = 0 # you can change this value around\n\nif x in A:\n  indicator_A_x = 1\nelse:\n  indicator_A_x = 0\n\nprint(f"indicator function of A and x: {indicator_A_x}")\n')),(0,i.kt)("h3",{id:"syntax-sugar-ternary-operator"},"Syntax Sugar: Ternary Operator"),(0,i.kt)("p",null,'This "if ',(0,i.kt)("inlineCode",{parentName:"p"},"condition"),' is true then this value, else this other value"\nstructure shows up quite frequently.'),(0,i.kt)("p",null,"The syntax sugar for this is: ",(0,i.kt)("inlineCode",{parentName:"p"},"value_t if condition else value_f"),".\nWe call this the ",(0,i.kt)("em",{parentName:"p"},"ternary operator"),",\nI guess because there are 3 operands (",(0,i.kt)("inlineCode",{parentName:"p"},"value_t"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"condition"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"value_f"),")."),(0,i.kt)("p",null,"The way to read this is that if ",(0,i.kt)("inlineCode",{parentName:"p"},"condition")," is/evaluates to ",(0,i.kt)("inlineCode",{parentName:"p"},"True"),",\nthe ternary expression evaluates to ",(0,i.kt)("inlineCode",{parentName:"p"},"value_t"),",\nif ",(0,i.kt)("inlineCode",{parentName:"p"},"condition")," is/evaluates to ",(0,i.kt)("inlineCode",{parentName:"p"},"False"),", it evaluates to ",(0,i.kt)("inlineCode",{parentName:"p"},"value_f"),"."),(0,i.kt)("p",null,"Behold the earlier example using this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Indicator_Ternary",live_py:!0,title:"Indicator_Ternary"},'A = {1,2,3,4,5}\nx = 0\ny = 3\n\nindicator_A_x = 1 if x in A else 0\nindicator_A_y = 1 if y in A else 0\n\nprint(f"indicator function of A and x: {indicator_A_x}")\nprint(f"indicator function of A and y: {indicator_A_y}")\n')),(0,i.kt)("p",null,"A 4-line if-else statement has become a 1-line ternary operator."),(0,i.kt)("h2",{id:"mapping-and-comprehe
1nsions"},"Mapping and Comprehensions"),(0,i.kt)("h3",{id:"setting-mapping"},"Setting: Mapping"),(0,i.kt)("p",null,"Often we find ourselves wanting to performs some operation, function,\nor transformation on every element in a collection.\nWe call this ",(0,i.kt)("em",{parentName:"p"},"mapping")," a operation/function/transformation over the collection,\nand it is a very frequent thing to do."),(0,i.kt)("p",null,'For example, say I wanted a list of the first 10 square numbers.\nThis could be done by taking a list of the numbers 1 to 10, and squaring all of them.\nThat "squaring all of them" is an operation (squaring) being performed on all\nelements in the collection. That is mapping.'),(0,i.kt)("p",null,"Code for that could look like:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Squares_Iteration",live_py:!0,title:"Squares_Iteration"},"squares = []\nfor i in range(1, 11):\n  squares.append(i ** 2)\nprint(squares)\n")),(0,i.kt)("p",null,"Abstractly: I am mapping the squaring over the range, and storing the result."),(0,i.kt)("h3",{id:"syntax-sugar-comprehensions"},"Syntax Sugar: Comprehensions"),(0,i.kt)("p",null,"We can get that list ",(0,i.kt)("inlineCode",{parentName:"p"},"squares")," in 3 fairly straightforward lines,\n",(0,i.kt)("strong",{parentName:"p"},"but we can do better"),"."),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},"Comprehensions")," are a way to create a collection based on iterating over\nsome other collection."),(0,i.kt)("p",null,"The syntax sugar for list comprehensions is: ",(0,i.kt)("inlineCode",{parentName:"p"},"[expression for var_name in collection]"),".\nEvery element in ",(0,i.kt)("inlineCode",{parentName:"p"},"collection")," is iterated over and assigned to ",(0,i.kt)("inlineCode",{parentName:"p"},"var_name")," in turn\n(the for in ",(0,i.kt)("inlineCode",{parentName:"p"},"for var_name in collection")," is exactly like a for loop).\n",(0,i.kt)("inlineCode",{parentName:"p"},"expression")," may make use of the variable named ",(0,i.kt)("inlineCode",{parentName:"p"},"var_name"),", and is evaluated for each\nelement in ",(0,i.kt)("inlineCode",{parentName:"p"},"collection"),". And the results are bundled together in a list."),(0,i.kt)("p",null,"Behold the earlier example using this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=List_Comprehension",live_py:!0,title:"List_Comprehension"},"squares = [i ** 2 for i in range (1, 11)]\nprint(squares)\n")),(0,i.kt)("p",null,"Note the congruences with the earlier less-sugary version."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The ",(0,i.kt)("inlineCode",{parentName:"li"},"[]")," are necessary to note we are making a list."),(0,i.kt)("li",{parentName:"ul"},"The ",(0,i.kt)("inlineCode",{parentName:"li"},"for i in range(1, 11)")," is exactly the same."),(0,i.kt)("li",{parentName:"ul"},"The ",(0,i.kt)("inlineCode",{parentName:"li"},".append(i ** 2)")," becomes the ",(0,i.kt)("inlineCode",{parentName:"li"},"i ** 2")," at the front in the comprehension.")),(0,i.kt)("h2",{id:"filtering-and-comprehensions"},"Filtering and Comprehensions"),(0,i.kt)("h3",{id:"setting-filtering"},"Setting: Filtering"),(0,i.kt)("p",null,"Often we find ourselves wanting to select only the elements of a collection\nthat satisfy some property.\nWe call this ",(0,i.kt)("em",{parentName:"p"},"filtering")," the collection based on some property/criteria,\nand it is also a very frequent thing to do."),(0,i.kt)("p",null,"For example, say I have a list of numbers and wanted only the even numbers in that list.\nI could use a conditional to add only the elements I want to my list of evens, like so:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Evens_Iteration",live_py:!0,title:"Evens_Iteration"},'nums = list(range(10,55,3))\nprint(f"nums : {nums}")\n\nevens = []\nfor i in nums:\n  if i % 2 == 0:\n    evens.append(i)\nprint(f"evens: {evens}")\n')),(0,i.kt)("h3",{id:"syntax-sugar-more-comprehensions"},"Syntax Sugar: More Comprehensions"),(0,i.kt)("p",null,"We can get that list ",(0,i.kt)("inlineCode",{parentName:"p"},"evens")," in 4 fairly straightforward lines,\nbut again, ",(0,i.kt)("strong",{parentName:"p"},"we can do better"),"."),(0,i.kt)("p",null,"Comprehensions also have built in filtering.\nThis gives us more general list comprehensions of the from:\n",(0,i.kt)("inlineCode",{parentName:"p"},"[expression for var_name in collection if condition]"),"."),(0,i.kt)("p",null,"This is just like before, except now ",(0,i.kt)("inlineCode",{parentName:"p"},"expression")," is only considered\nfor elements where ",(0,i.kt)("inlineCode",{parentName:"p"},"condition")," is true (",(0,i.kt)("inlineCode",{parentName:"p"},"condition")," may make use of ",(0,i.kt)("inlineCode",{parentName:"p"},"var_name"),")."),(0,i.kt)("p",null,"Behold the earlier example using this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Evens_Comprehension",live_py:!0,title:"Evens_Comprehension"},'nums = list(range(10,55,3))\nprint(f"nums : {nums}")\n\nevens = [i for i in nums if i % 2 == 0]\nprint(f"evens: {evens}")\n')),(0,i.kt)("p",null,"Note the congruences with the earlier less-sugary version."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The ",(0,i.kt)("inlineCode",{parentName:"li"},"[]")," for the list."),(0,i.kt)("li",{parentName:"ul"},"The ",(0,i.kt)("inlineCode",{parentName:"li"},"for i in nums")," is exactly the same."),(0,i.kt)("li",{parentName:"ul"},"The ",(0,i.kt)("inlineCode",{parentName:"li"},"if i % 2 == 0")," is exactly the same."),(0,i.kt)("li",{parentName:"ul"},"The ",(0,i.kt)("inlineCode",{parentName:"li"},".append(i)")," becomes the ",(0,i.kt)("inlineCode",{parentName:"li"},"i")," at the front in the comprehension.")),(0,i.kt)("p",null,"The nesting out-to-in of the for loop and if statement becomes the\nexact same statements written left-to-right, with the expression brought to the front\n(and surrounded by square brackets to indicate this is to be a list)."),(0,i.kt)("p",null,"Another example, where the ",(0,i.kt)("inlineCode",{parentName:"p"},"expression")," part is non-trivial.\nWe could get all halves of even numbers in a list."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Divide_Evens",live_py:!0,title:"Divide_Evens"},'nums = list(range(10,55,3))\nprint(f"nums       : {nums}")\n\n# Iterative Approach\nhalves_iter = []\nfor i in nums:\n  if i % 2 == 0:\n    halves_iter.append(i // 2)\nprint(f"halves_iter: {halves_iter}")\n\n# Comprehension\nhalves_comp = [i//2 for i in nums if i % 2 == 0]\nprint(f"halves_comp: {halves_comp}")\n')),(0,i.kt)("p",null,"Again, notice how the looping+branching portion is just flattened (out->in to left->right),\nwith the expression for the new element being brought to the front of the comprehension."),(0,i.kt)("p",null,"And one more, maybe for a given number, we want to get\nall factors of that number (all numbers that divide it)."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Factors",live_py:!0,title:"Factors"}
1,'num = 60 # play with this value\nprint(f"number: {num}")\n\n# Iterative Approach\nfactors_iter = []\nfor i in range(1,num):\n  if num % i == 0:\n    factors_iter.append(i)\nprint(f"factors_iter: {factors_iter}")\n\n# Comprehension\nfactors_comp = [i for i in range(1,num) if num % i == 0]\nprint(f"factors_comp: {factors_comp}")\n')),(0,i.kt)("hr",null),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Material from here on was not part of the lecture.\nThis is basically a bunch of examples leveraging syntax sugar,\nbecause I enjoy playing around with it a little too much.")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"more-comprehension-types"},"More Comprehension Types"),(0,i.kt)("p",null,"For showing off the comprehension syntax,\nit is sufficient to only talk about list comprehensions.\nBut there are other structure this exists for."),(0,i.kt)("p",null,"There are also set comprehensions, which are much the same except for ",(0,i.kt)("inlineCode",{parentName:"p"},"{}")," on the outside."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Set_Comprehension",live_py:!0,title:"Set_Comprehension"},"squares = {i ** 2 for i in range (1, 11)}\nprint(squares)\n")),(0,i.kt)("p",null,"There are also dictionary comprehensions,\nwhich are much the same except for ",(0,i.kt)("inlineCode",{parentName:"p"},"{}")," on the outside and the ",(0,i.kt)("inlineCode",{parentName:"p"},"expression"),"\nneeds be of the form ",(0,i.kt)("inlineCode",{parentName:"p"},"key:value"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Dictionary_Comprehension",live_py:!0,title:"Dictionary_Comprehension"},"squares = {i:i ** 2 for i in range (1, 11)}\nprint(squares)\n")),(0,i.kt)("p",null,"There is not exactly tuple comprehension, but you can do something that feels like it."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Tuple_Comprehension",live_py:!0,title:"Tuple_Comprehension"},"squares = tuple(i ** 2 for i in range (1, 11))\nprint(squares)\n")),(0,i.kt)("p",null,"in practice, you are generally going to do list comprehension and not\nbootleg tuple comprehension."),(0,i.kt)("details",null,(0,i.kt)("summary",null,(0,i.kt)("b",null,"Extra: What About Just Parentheses?")),(0,i.kt)("p",null,"You might be wondering why wrapping the ",(0,i.kt)("inlineCode",{parentName:"p"},"i ** 2 for i in range (1, 11)"),"\nin parentheses isn't tuple comprehension."),(0,i.kt)("p",null,"The answer is basically that that syntax is already used for something called\n",(0,i.kt)("em",{parentName:"p"},"generators"),', which I am not going to get into.\nIf you were curious, searches for "generators", "yield", and "generator comprehension"\
1nwould probably get you that stuff.'),(0,i.kt)("p",null,"And in fact, I think that bootleg tuple comprehension from earlier is technically\njust casting a generator to a tuple."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Generator_Comprehension",live_py:!0,title:"Generator_Comprehension"},"squares = (i ** 2 for i in range (1, 11))\nprint(squares)\nsquares = tuple(squares)\nprint(squares)\n"))),(0,i.kt)("h2",{id:"chaining"},"Chaining"),(0,i.kt)("h3",{id:"ternary-operators-1"},"Ternary Operators"),(0,i.kt)("p",null,"You can chain ternary operators, sort of like an if-elif-else statement.\nAnd seeing the intuition for that comes from transforming an if-elif-else statement."),(0,i.kt)("p",null,"Imagine, as a motivating example, you have a number ",(0,i.kt)("inlineCode",{parentName:"p"},"num"),",\nand want to get its sign (-1 for negative numbers, 0 for 0, and 1 for positive numbers).\nYou could do this with an if-elif-else."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},"if num > 0:\n  sign = 1\nelif num < 0:\n  sign = -1\nelse:\n  sign = 0\n")),(0,i.kt)("p",null,"The if-elif-else is equivalent to an if-else with another if-else in the outer else block.\nIt looks worse now, but we can start introducing ternary operators."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},"if num > 0:\n  sign = 1\nelse:\n  if num < 0:\n    sign = -1\n  else:\n    sign = 0\n")),(0,i.kt)("p",null,"We can transform the inner if-else into a ternary operator."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"if num > 0:\n  sign = 1\nelse:\n  sign = -1 if num < 0 else 0\n")),(0,i.kt)("p",null,"And by taking ",(0,i.kt)("inlineCode",{parentName:"p"},"-1 if num < 0 else 0")," as its own expression,\nwe can replace the outer if-else with a ternary operator."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"sign = 1 if num > 0 else -1 if num < 0 else 0\n")),(0,i.kt)("p",null,"This reduces a 6-line if-elif-else to a 1-line ternary operator chain.\nRunnable code below:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Sign",live_py:!0,title:"Sign"},'def sign(num):\n  return 1 if num > 0 else -1 if num < 0 else 0\n\nprint(f"sign(12) : {sign(12):>2d}")\nprint(f"sign(4)  : {sign(4):>2d}")\nprint(f"sign(0)  : {sign(0):>2d}")\nprint(f"sign(-2) : {sign(-2):>2d}")\nprint(f"sign(-7) : {sign(-7):>2d}")\n')),(0,i.kt)("h3",{id:"comprehensions"},"Comprehensions"),(0,i.kt)("p",null,'This idea that the comprehension is just "the flattened-out for-if structure with\nthe final expression brought to the front" generalises to arbitrary for loop nesting.'),(0,i.kt)("p",null,"Consider this iterative approach to flattening a list of lists\n(making a list out of all the inner-list elements):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Flatten_Iteration",live_py:!0,title:"Flatten_Iteration"},"ll = [[1,2,3], [4,5], [6,7,8,9]]\n\n# Iterative Approach\nflat_iter = []\nfor l in ll:\n  for i in l:\n    flat_iter.append(i)\nprint(flat_iter)\n")),(0,i.kt)("p",null,"Those nested for loops can both be used in a comprehension,\nwith the outer loop going before the inner."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Flatten_Comprehension",live_py:!0,title:"Flatten_Comprehension"},"ll = [[1,2,3], [4,5], [6,7,8,9]]\n\n# Comprehension\nflat_comp = [i for l in ll for i in l]\nprint(flat_comp)\n")),(0,i.kt)("p",null,"Outer-to-inner in iteration land becomes left-to-right in comprehension land,\nwith the expression being brought to the front."),(0,i.kt)("p",null,"Another example of this, imagine you wanted to get all integer 2D coordinates that lie\nwithin some circle of a given radius centred at the origin."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Circle",live_py:!0,title:"Circle"},"r = 3\n\n# Iterative Approach\npoints_iter = []\nfor x in range(-r, r+1):\n  for y in range(-r, r+1):\n    if x ** 2 + y ** 2 <= r ** 2:\n      points_iter.append((x,y))\nprint(points_iter)\n\n# Comprehension\npoints_comp = [(x,y) for x in range(-r, r+1) for y in range(-r, r+1) if x ** 2 + y ** 2 <= r ** 2]\nprint(points_comp)\n")),(0,i.kt)("p",null,"Outer-to-inner to left-to-right, expression brought to the front."),(0,i.kt)("h2",{id:"apotheosis-more-exotic-examples"}
1,"Apotheosis (More Exotic Examples)"),(0,i.kt)("p",null,'Combining all these things can allow you to do some incredibly complex tasks in remarkably dense code.\nWhen fundamentals are cemented and you start incorporating these sorts of things,\nyou find yourself spending more time thinking "how am I going to write this code"\nthan writing code.\nBut when something you\'ve spent the time to schemingly craft works, it feels really good.'),(0,i.kt)("p",null,"I'll have some examples of more complicated things here as I think of them."),(0,i.kt)("p",null,'In the following I have a list of adjectives and nouns,\nand I want to get all combinations, with the correct article too.\nFor instance, "red" and "house" would produce "a red house".'),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Adj_Noun",live_py:!0,title:"Adj_Noun"},'adjs = ["red", "orange", "blue", "enormous", "small", "awful", "scary"]\nnouns = ["fruit", "house", "snake", "fate"]\nadj_nouns = {f"{\'an\' if adj[0] in \'aeiou\' else \'a\'} {adj} {noun}" for adj in adjs for noun in nouns}\nprint("\\n".join(adj_nouns))\n')),(0,i.kt)("p",null,"There are chained for loops and an f-string expression with a ternary inside.\nFor densities sake, I'm doing ",(0,i.kt)("inlineCode",{parentName:"p"},'"\\n".join()')," for prints instead of a for loop."),(0,i.kt)("p",null,"In the following, instead of a list of factors for a number like earlier,\nI want a dictionary with numbers as keys and sets of factors as values."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Factors_Dict",live_py:!0,title:"Factors_Dict"},'nums = [12, 25, 50, 60, 100]\nfactor_dict = {num:{i for i in range(1,num) if num % i == 0} for num in nums}\nprint("\\n".join([f"{num:>3d}: {factors}" for num,factors in factor_dict.items()]))\n')),(0,i.kt)("p",null,"There is a set comprehension inside the dictionary comprehension\n(since the value is a set of factors).\nAs for the print: I could have have done a for loop like a sane person,\nbut I can also do ",(0,i.kt)("inlineCode",{parentName:"p"},".join()")," on a list comprehension.\nThis print list comprehension also leverages destructuring for convenience."),(0,i.kt)("p",null,"The following was code I made to display a circle based on the points in said circle.\nI chose to cut off the most extreme points (so displaying from ",(0,i.kt)("span",{parentName:"p",className:"math math-inline"},(0,i.kt)("span",{parentName:"span",className:"katex"},(0,i.kt)("span",{parentName:"span",className:"katex-mathml"},(0,i.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,i.kt)("semantics",{parentName:"math"},(0,i.kt)("mrow",{parentName:"semantics"},(0,i.kt)("mo",{parentName:"mrow"},"\u2212"),(0,i.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,i.kt)("mi",{parentName:"mrow"},"r"),(0,i.kt)("mo",{parentName:"mrow"},"\u2212"),(0,i.kt)("mn",{parentName:"mrow"},"1"),(0,i.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,i.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"-(r-1)")))),(0,i.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,i.kt)("span",{parentName:"span",className:"base"},(0,i.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,i.kt)("span",{parentName:"span",className:"mord"},"\u2212"),(0,i.kt)("span",{parentName:"span",className:"mopen"},"("),(0,i.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,i.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,i.kt)("span",{parentName:"span",className:"mbin"},"\u2212"),(0,i.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,i.kt)("span",{parentName:"span",className:"base"},(0,i.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,i.kt)("span",{parentName:"span",className:"mord"},"1"),(0,i.kt)("span",{parentName:"span",className:"mclose"},")")))))," to ",(0,i.kt)("span",{parentName:"p",className:"math math-inline"},(0,i.kt)("span",{parentName:"span",className:"katex"},(0,i.kt)("span",{parentName:"span",className:"katex-mathml"},(0,i.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,i.kt)("semantics",{parentName:"math"},(0,i.kt)("mrow",{parentName:"semantics"},(0,i.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,i.kt)("mi",{parentName:"mrow"},"r"),(0,i.kt)("mo",{parentName:"mrow"},"\u2212"),(0,i.kt)("mn",{parentName:"mrow"},"1"),(0,i.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,i.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"(r-1)")))),(0,i.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,i.kt)("span",{parentName:"span",className:"base"},(0,i.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,i.kt)("span",{parentName:"span",className:"mopen"},"("),(0,i.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,i.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,i.kt)("span",{parentName:"span",className:"mbin"},"\u2212"),(0,i.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,i.kt)("span",{parentName:"span",className:"base"},(0,i.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,i.kt)("span",{parentName:"span",className:"mord"},"1"),(0,i.kt)("span",{parentName:"span",className:"mclose"},")")))))," inclusive)."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py",metastring:"live_py title=Print_Circle",live_py:!0,title:"Print_Circle"},'r = 20\npoints = [(x,y) for x in range(-r, r+1) for y in range(-r, r+1) if x ** 2 + y ** 2 <= r ** 2]\nprint("\\n".join([" ".join([("\u2022" if (x,y) in points else " ") for x in range(-r+1, r)]) for y in range(r-1, -r, -1)]))\n')),(0,i.kt)("p",null,"There is a ",(0,i.kt)("inlineCode",{parentName:"p"},".join()")," on a list comprehension, whose expression is itself\na ",(0,i.kt)("inlineCode",{parentName:"p"},".join()")," on a list comprehension, whose expression is a ternary operator."))}c.isMDXComponent=!0}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.