This commit is contained in:
James Turk 2024-10-09 22:36:38 -05:00
parent 5b4753f57f
commit 64b09cdaa5
3 changed files with 900 additions and 8 deletions

View File

@ -10,7 +10,7 @@
"toc-hr-collapsed": true "toc-hr-collapsed": true
}, },
"source": [ "source": [
"## Python Objects & References\n", "# Python Objects & References\n",
"\n", "\n",
"Everything in Python is an `object`. An object is a piece of memory with values & associated operations.\n", "Everything in Python is an `object`. An object is a piece of memory with values & associated operations.\n",
"\n", "\n",
@ -60,7 +60,7 @@
} }
}, },
"source": [ "source": [
"#### objects are typed, not variables\n", "## objects are typed, not variables\n",
"\n", "\n",
"![shared_ref2.png](attachment:shared_ref2.png)\n", "![shared_ref2.png](attachment:shared_ref2.png)\n",
" -- Learning Python 2013" " -- Learning Python 2013"
@ -75,7 +75,7 @@
} }
}, },
"source": [ "source": [
"### Shared references\n", "## Shared references\n",
"\n", "\n",
"Setting a variable to a new value does not alter the original.\n", "Setting a variable to a new value does not alter the original.\n",
"\n", "\n",
@ -271,7 +271,7 @@
"id": "99744fac-c1d9-4532-a7d4-0dcbc1a0d2a3", "id": "99744fac-c1d9-4532-a7d4-0dcbc1a0d2a3",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Garbage Collection\n", "## Garbage Collection\n",
"\n", "\n",
"Python is a garbage collected language. \n", "Python is a garbage collected language. \n",
"\n", "\n",
@ -414,7 +414,7 @@
"id": "9a48460e-a342-4d18-8383-b84483a3a010", "id": "9a48460e-a342-4d18-8383-b84483a3a010",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### list / string example revisited" "### list / string mutability revisited"
] ]
}, },
{ {
@ -458,7 +458,7 @@
} }
}, },
"source": [ "source": [
"### Object Creation\n", "### Aside: Object Creation Quirk\n",
"\n", "\n",
" Each time you generate a new value in your script by running an expression, Python creates a new object (i.e., a chunk of memory) to represent that value.\n", " Each time you generate a new value in your script by running an expression, Python creates a new object (i.e., a chunk of memory) to represent that value.\n",
" \n", " \n",
@ -523,7 +523,7 @@
} }
}, },
"source": [ "source": [
"### Copying\n", "## copy & deepcopy\n",
"\n", "\n",
"If `y = x` does not make a copy, how can we get one?\n", "If `y = x` does not make a copy, how can we get one?\n",
"\n", "\n",

View File

@ -5,7 +5,7 @@
"id": "eeb9e8e4", "id": "eeb9e8e4",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Functions" "# Functions"
] ]
}, },
{ {

View File

@ -0,0 +1,892 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "de726aba-1fb3-4b2e-be01-825ced7a9093",
"metadata": {},
"source": [
"# Functional Programming\n",
"\n",
"The style of programming we've been doing is called **imperative** or **procedural**. Statements run in sequence and change a program's state.\n",
"\n",
"As we said early on, Python is multi-paradigm. \n",
"\n",
"> \"[...] practicality beats purity.\"\n",
"> \n",
"> - The Zen of Python\n",
"\n",
"Languages like LISP, Haskell, Racket are purely functional & differ significantly from procedural & object-oriented languages.\n",
"\n",
"Functional programming uses a more mathematical definition of functions. Instead of the recipe model of procedural programming, mathematical functions take input(s) and return an output. \n",
"\n",
"These functions do not have the concept of \"state\", that is, calling a function in math creates a mapping from inputs to outputs.\n",
"\n",
"When we call `sin(x)` we do not speak of it modifying its inputs, just returning a value.\n",
"\n",
"Similarly, when we workin a functional style we'll often write smaller functions that we chain together, instead of long procedures that rely on internal state.\n",
"\n",
"Python has many features that stem from pure functional languages & support functional programming:\n",
"\n",
"- Functions as first class objects\n",
"- Lambda expressions\n",
"- map/filter\n",
"- `functools`\n",
"- comprehensions\n",
"\n",
"## Functions are \"first-class objects\"\n",
"\n",
"A key feature of Python that makes it possible to write code in the functional style is the fact that functions are objects. (Everything in Python is an object.)\n",
"\n",
"This means functions don't have special rules about how they can be used, any variable can reference a function. (Remember, a variable is an association between a name & object.)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "72bee260-b4d1-4c61-a689-8799d4dfb7c6",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"def echo(message):\n",
" print(message)\n",
" print(message)\n",
" \n",
"print(f\"echo = {echo}\")\n",
"print(f\"type(echo) = {type(echo)}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39ee1708-c3ec-47ed-9c87-2124fa55b57f",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# we can assign other names to objects, including functions\n",
"\n",
"x = echo\n",
"\n",
"x(\"hello\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5a175699-fd00-4e69-a534-2d25085550d2",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"id(x), id(echo)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "52de62a9-af2f-4fbe-becf-2c315ddb9c77",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# we can also store functions in other types\n",
"\n",
"func_list = [print, echo, print, echo]\n",
"for i, func in enumerate(func_list):\n",
" func(i)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6cad8105-8a71-4b8a-926c-dfa0f635e7ad",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# dictionaries too\n",
"func_mapping = {False: print, True: echo}\n",
"\n",
"print_twice = True\n",
"func_mapping[True](\"twice\")\n",
"\n",
"print_twice = False\n",
"func_mapping[print_twice](\"once\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "54247b2d-d5fe-4bbb-990a-bbaf6660f89d",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "d89416fb-e0e7-48ca-9ca7-9fea5525b273",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# we can pass functions into other functions\n",
"\n",
"def add(a, b):\n",
" return a + b\n",
"\n",
"def sub(a, b):\n",
" return a - b\n",
"\n",
"def perform_op(op_func, a, b):\n",
" return op_func(a, b)\n",
"\n",
"print(\"add, 3, 4 = \", perform_op(add, 3, 4))\n",
"print(\"sub, 3, 4 = \", perform_op(sub, 3, 4))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d0192ae3-d175-4140-a8a9-ea664ee1e015",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# and we can return functions from other functions\n",
"\n",
"def get_op(name):\n",
" if name == \"div\":\n",
" def f(a, b):\n",
" return a / b\n",
" elif name == \"mod\":\n",
" def f(a, b):\n",
" return a % b\n",
" return f"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0f558df5-c1ae-4a20-9820-8a6d83878302",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"fn = get_op(\"mod\")\n",
"perform_op(fn, 10, 3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9039813a-a943-40e1-802f-f230547ffa2d",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = [(\"Nick\", 1), (\"Yusong\", 9), (\"Emma\", 100)]\n",
"\n",
"def negate(y):\n",
" return -y\n",
"\n",
"x.sort(key=lambda item: item[1])\n",
"print(x)\n",
"\n",
"#x.sort(key=negate)\n",
"#print(x)"
]
},
{
"cell_type": "markdown",
"id": "06fdddbe-0903-452c-8528-e5a0b8489f50",
"metadata": {},
"source": [
"## lambda functions\n",
"\n",
"Python also provides another way to generate function objects.\n",
"\n",
"These are called lambda functions (aka anonymous functions), which:\n",
"\n",
"- Are expressions that return a function object that can be called later without providing a name (hence ``anonymous\")\n",
"- Can be used in places where def statement is not syntactically legal (inside a literal list, inlined as a function argument, etc.)\n",
"\n",
"The body of an lambda function is a single expression, not a block of statements. The body is similar to a return statement in a def statement.\n",
"\n",
"```python\n",
"\n",
"lambda arg1, arg2: expression\n",
"\n",
"# essentially the same as\n",
"\n",
"def __(arg1, arg2):\n",
" return expression\n",
"```\n",
"\n",
"(0 or more arguments, but *must* have an expression)"
]
},
{
"cell_type": "markdown",
"id": "bf3e3782-2baf-4a04-8a23-252d39ad5dd3",
"metadata": {},
"source": [
"## Reminder: expressions vs. statements\n",
"\n",
"Everything in Python is either an expression or a statement. \n",
"\n",
"An expression evaluates to a value, examples include:\n",
"\n",
"* `42`\n",
"* `\"hello world\"`\n",
"* `10 * 5`\n",
"* `f(1, 2, 3)`\n",
"* `[1, 2, 3]`\n",
"* `l[0]` \n",
"* `lambda arg1, arg2: arg1 + arg2`\n",
"\n",
"Notice that all of these could be found on the right hand side of an assignment (e.g. `x = 10 * 5`)\n",
"\n",
"Expresssions are valid in assignment, function calls, sequence values, etc. (Anywhere a value is needed.)\n",
"\n",
"```\n",
"# in assignment\n",
"x = 42\n",
"x = 10 * 5\n",
"x = [1, 2, 3]\n",
"\n",
"# in function calls\n",
"f(42)\n",
"f(10 * 5)\n",
"f([1, 2, 3])\n",
"\n",
"# in complex types\n",
"[42, [1, 2, 3], lambda x: x**2]\n",
"{10*5: f(10, 5)}\n",
"```\n",
"\n",
"To contrast, statements perform an action.\n",
"\n",
"* `x = 1`\n",
"* `if x: ...`\n",
"* `def f(a): ...` \n",
"* `import math`\n",
"\n",
"They are prohibted where types are required:\n",
"\n",
"```\n",
" # not allowed\n",
"x = if y > 0: \n",
" 7\n",
"\n",
"z = def f(a): \n",
" ...\n",
"```\n",
"\n",
"A statement will often have multiple expressions within it. Many statements (but not all) use indented blocks.\n",
"\n",
"When it comes to `lambda`:\n",
"* a `lambda` defines a function that maps input to a single expression, `def` can be used if more was needed\n",
"* a `lambda` is itself an expression, it can be used anywhere other expresssions are needed"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68f51efb-9a62-4303-afe7-3639be9cc395",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# can fit places a function definition can't\n",
"# such as being used as a parameter\n",
"perform_op(lambda a, b: a * b, 5, 6)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "15e0c8eb-d8af-4e85-a53d-06820961b5e8",
"metadata": {},
"outputs": [],
"source": [
"lambda s: s.upper()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39bf652e-f85d-4a66-96bf-0ae21054be26",
"metadata": {},
"outputs": [],
"source": [
"# can be assigned to a variable\n",
"mul = lambda a, b: a * b\n",
"mul(5, 6)\n",
"\n",
"# same as\n",
"def mul2(a, b):\n",
" return a * b"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1eb1c524-30e1-4b20-b2a9-7b078e906c61",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"type(mul), type(mul2)"
]
},
{
"cell_type": "markdown",
"id": "51a501aa-4533-4d34-bb6d-8185521cf8e7",
"metadata": {},
"source": [
"General rule: If you're giving a lambda a name, use a function."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "425bb2b5-bb3a-448e-a6fb-9060579f588a",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# common use case\n",
"names = [\"adam\", \"Ziwe\", \"Bo\", \"JENNY\"]\n",
"names.sort()\n",
"print(names) # case sensitive, lower-case a comes after Z"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a1477f21-65e6-4925-8da7-8321cb801eac",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"names.sort(key = lambda x: x.upper())\n",
"print(names)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a773d32c-b061-410a-a4e4-f7afe8a83529",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "308a3691-8873-4166-afec-089a653333d4",
"metadata": {},
"source": [
"## Functional Methods\n",
"\n",
"Python also has several built in methods that are useful when writing programs with a functional mindset.\n",
"\n",
"`map`, `filter`, `functools`\n",
"\n",
"#### `map(function, iterable1, [...iterableN])`\n",
"\n",
"Returns a new iterable that calls `function` with parameters from `iterable1 ... iterableN`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3e2768f5-8817-4dfc-8ff5-72a774f499fa",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"def add_two(x):\n",
" return x + 2\n",
"\n",
"for x in map(add_two, [1, 2, 3]):\n",
" print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cd940ce1-c28a-4646-8846-f199f586cad8",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"help(map)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "04106e30-95df-432a-b6b0-40fcc58f51e5",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = list(map(add_two, [1, 2, 3]))\n",
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fba295ed-9dcb-4cbb-8b7e-3b0ff2965639",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# commonly used with lambdas\n",
"\n",
"for x in map(lambda x, y, z: x * y + z, (\"A\", \"B\", \"C\"), [\"!\", \"?\", \".\"]):\n",
" print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c4e1d7f9-c111-44ff-8525-de147f90aa56",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# operator module contains all of the common operators\n",
"import operator\n",
"\n",
"operator.sub(20, 5)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e6383ce1-6e06-44a4-beb2-1e946b81c483",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"list(map(operator.sub, [20, 19], [10, 9]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b58441e4-ba95-43e4-8151-dd25e1c7efd1",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# the result of `map` is an iterable\n",
"\n",
"# possible to pass into set or list \n",
"# or anywhere you can pass an iterable\n",
"set(map(lambda x: x * 3, (\"A\", \"B\", \"C\")))"
]
},
{
"cell_type": "markdown",
"id": "a58bbdf5-afb7-466b-886e-618ea0411ab3",
"metadata": {},
"source": [
"#### `filter(function, iterable)` \n",
"\n",
"returns an iterable that contains all items from iterable for which `function(item)` returns True"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7eaab05d-2b8e-45fa-ad97-565c2edac0f6",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"list(map(lambda s: s.title(), filter(str.isupper, [\"a\", \"ABC\", \"AbCdeF\", \"XYZ\"])))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c4a69097-c30c-4096-b69b-f3fa89a1bc7f",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"list(filter(lambda s: s.isupper(), [\"a\", \"ABC\", \"AbCdeF\", \"XYZ\"]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6852f961-f20d-4c82-8da4-c7bdcfc1ae4b",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"list(map(lambda s: s.lower(), filter(lambda s: s.isupper(), [\"a\", \"ABC\", \"AbCdeF\", \"XYZ\"])))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a195957c-0e89-4d3e-9b85-ace9e1f84e5d",
"metadata": {},
"outputs": [],
"source": [
"g = (x**2 for x in filter(lambda x: x % 2 != 0, range(20)))\n",
"list(g)"
]
},
{
"cell_type": "markdown",
"id": "aab35319-a066-414f-a0b5-d66412d41061",
"metadata": {},
"source": [
"#### functools"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f2529705-fd60-45ed-ae13-0a77f745c201",
"metadata": {},
"outputs": [],
"source": [
"import functools\n",
"[name for name in dir(functools) if name[0].islower()]"
]
},
{
"cell_type": "markdown",
"id": "67d3bc6f-f3a4-4b7e-984f-87d22ad3925f",
"metadata": {},
"source": [
"``functools.reduce(function, iterable[, initializer])``\n",
"\n",
"Apply ``function`` to pairs of items successively and return a single value as the result. You can optionally specify the initial value.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a623edc8-08cb-41d0-8b2c-fd99619fed73",
"metadata": {},
"outputs": [],
"source": [
"import functools \n",
"import operator \n",
"\n",
"#accumulator = 0\n",
"#for item in my_list:\n",
"# accumulator += item\n",
"\n",
"# 1st iteration: Call operator.add(1,2) -> 3 \n",
"# 2nd iteration: Call operator.add(3,3) -> 6 \n",
"# 3rd iteration: Call operator.add(6,4) -> 10 \n",
"# final result = 10 \n",
"functools.reduce(operator.add, [1,2,3,4])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5081e0e6-424b-472b-b0b0-f0c2bfa1344e",
"metadata": {},
"outputs": [],
"source": [
"names = [\"Ben\", \"Martha\", \"Susan\"]\n",
"# 1st iteration: call f(0, \"Ben\") -> 0 + len(\"Ben\") -> 3\n",
"# 2nd iteration: call f(3, \"Martha\") -> 3 + len(\"Martha\") -> 9\n",
"# 3rd iteration: call f(9, \"Susan\") -> 9 + len(\"Susan\") -> 14\n",
"functools.reduce(lambda a, b: a + len(b), names, 0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6fd2afda-b07f-45f6-9a82-6bc50665af6c",
"metadata": {},
"outputs": [],
"source": [
"# What happens if you pass in an initial value \n",
"# 1st iteration: Call operator.mul(2,1) -> 2 \n",
"# 2nd iteration: Call operator.mul(2,2) -> 4 \n",
"# 3rd iteration: Call operator.mul(4,3) -> 12 \n",
"# 4th iteration: Call operator.mul(12,4) -> 48 \n",
"# Final result = 48 \n",
"functools.reduce(operator.mul, [1,2,3,4], 0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "74e7a581-3f79-4be3-ba9d-f354b1df13a1",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"functools.reduce(lambda a,b: a+b, [], 0)"
]
},
{
"cell_type": "markdown",
"id": "b0dea67f-aaf8-43aa-a166-7bbfd4d2496d",
"metadata": {},
"source": [
"```functools.partial(func, *args, **kwargs)```\n",
"\n",
"`functools.partial` returns a new function that \"binds\" any passed args & kwargs, and leaves other parameters unbound."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5a23eb2c-8324-4ff1-beb2-bca7ff5dbbe1",
"metadata": {},
"outputs": [],
"source": [
"import operator\n",
"operator.mul(2, 10)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "70988dc5-1a32-4316-bb9a-d4be646dd2c2",
"metadata": {},
"outputs": [],
"source": [
"import functools\n",
"negate = functools.partial(operator.mul, -1)\n",
"negate(5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7b2d87c2-903a-4b48-a012-3e3b0b03584f",
"metadata": {},
"outputs": [],
"source": [
"def calls_twice(f):\n",
" print(f())\n",
" print(f())\n",
" \n",
"\n",
"g = functools.partial(operator.mul, 4, 4)\n",
"#print(g())\n",
"calls_twice(g)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0e2ffbc6-e05f-401e-b569-273c61f6d514",
"metadata": {},
"outputs": [],
"source": [
"print_ex = functools.partial(print, \"x\", sep=\"!\")\n",
"print_ex(\"a\", \"b\", \"c\")\n",
"print(\"x\", \"a\", \"b\", \"c\", sep=\"!\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6e9be6b5-0a68-4de6-8289-31fb5095d31f",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"print_foo = functools.partial(print, foo=\"x\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "10c4769b-7b1f-4fbc-924d-8b3e5de7fb93",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"print_foo(\"hello\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "318556fb-eafa-44af-bcfd-0848b87b6e18",
"metadata": {},
"outputs": [],
"source": [
"def request_page(url, verify, cache=True, send_cookies=False, https_only=True):\n",
" pass\n",
"\n",
"secure_request = functools.partial(request_page, verify=True, https_only=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9b4c5678-2525-4822-93e3-77dd0f40213b",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"secure_request(\"\", verify=False)\n",
"sec"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "157ff803-8809-481e-bff4-1fa06d067963",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "5ba68ff2-42fd-441b-ac44-9d51bd9b6d8b",
"metadata": {},
"source": [
"## List Comprehensions\n",
"\n",
"Generate a new list from an existing iterable.\n",
"\n",
"Same syntax as generator expression but inside `[]`:\n",
"\n",
"```python\n",
"new_list = [expression for var in iterable]\n",
"\n",
"# or \n",
"\n",
"new_list = [expression for var in iterable if condition]\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "79029822-694a-445d-9776-48e05e94733b",
"metadata": {},
"outputs": [],
"source": [
"powers_of_two = [2 ** n for n in range(10)]\n",
"print(powers_of_two)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fe7d9640-165c-4887-a9f0-9e411fc8e031",
"metadata": {},
"outputs": [],
"source": [
"# possible to nest comprehensions, but beware readability\n",
"faces = (\"K\", \"Q\", \"J\")\n",
"suits = (\"♠\", \"♣\", \"♦\", \"♥\")\n",
"cards = [(face + suit) for face in faces for suit in suits if face != \"K\"]\n",
"print(cards)"
]
},
{
"cell_type": "markdown",
"id": "94a7b169-7930-4df5-a1ed-76f6bb0df14c",
"metadata": {},
"source": [
"## Set & Dict Comprehensions\n",
"\n",
"Also possible to make `set` and `dict` comprehensions by using `{}`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "24213ab6-3c6e-45df-8bb9-93b2d69c10fa",
"metadata": {},
"outputs": [],
"source": [
"powers_of_two_set = {2 ** n for n in [1,1,2,2,3,3,3,4,4,4]}\n",
"print(powers_of_two_set)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "95f3d657-39aa-4803-8fc7-4e736ebc5b20",
"metadata": {},
"outputs": [],
"source": [
"\n",
"powers_of_two_mapping = {n: f(n) for n in range(5) if n > 0}\n",
"print(powers_of_two_mapping)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7139c632-97cf-49a5-8abf-5b7516c1a401",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}