Skip to content

Commit

Permalink
Add a note on reference copying
Browse files Browse the repository at this point in the history
  • Loading branch information
mdpiper committed Aug 31, 2023
1 parent d9a3fbc commit d69d070
Showing 1 changed file with 280 additions and 2 deletions.
282 changes: 280 additions & 2 deletions lessons/python/more_fundamentals.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"id": "9bb0f300",
"metadata": {},
"source": [
"# Python language fundamentals II"
"# Loops, conditionals, and exceptions"
]
},
{
Expand Down Expand Up @@ -416,6 +416,280 @@
"The `try` statement is a key part of the [\"it's easier to ask forgiveness than permission\"](https://devblogs.microsoft.com/python/idiomatic-python-eafp-versus-lbyl/) programming style commonly used in Python."
]
},
{
"cell_type": "markdown",
"id": "1f1a3330-19e5-46fb-9dad-28ff9ea3ca88",
"metadata": {},
"source": [
"## A note on reference copying"
]
},
{
"cell_type": "markdown",
"id": "3a537e76-9599-4eb6-b489-12c1501e86b9",
"metadata": {},
"source": [
"Python displays interesting behavior when duplicating lists, dictionaries, and arrays through assignment.\n",
"\n",
"From the docs:\n",
"\n",
"> Assignment statements in Python do not copy objects, they create bindings between a target and an object.\n",
"\n",
"Let's explore this behavior and see how it can lead to unintended consequences."
]
},
{
"cell_type": "markdown",
"id": "5a6ab1da-a02c-4894-9bac-3fc4ebf41b31",
"metadata": {},
"source": [
"Start by creating two integer variables, `x` and `y`,\n",
"noting that `y` is assigned the initial value of `x`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f1111d97-95d6-42b7-ad95-e9c066af3eca",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = 5\n",
"y = x"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "751f4fca-5d55-4755-aec3-ebfd6483c705",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f3bc3987-17f4-4e33-ad0f-ef0170224e2d",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"y"
]
},
{
"cell_type": "markdown",
"id": "2a311d5d-7e59-4159-b72f-836e5f85ccbf",
"metadata": {},
"source": [
"Now change the value of `x`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1a7fb680-ed7a-4c92-ab71-aa8c9ef993b9",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = 10\n",
"x"
]
},
{
"cell_type": "markdown",
"id": "df6ee1f3-cbe4-4268-8437-6a2ac4db8c74",
"metadata": {},
"source": [
"Does the value of `y` change?"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d9fceea7-1b5e-410d-ba0b-2843947aab01",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"y"
]
},
{
"cell_type": "markdown",
"id": "9e064d7c-21dd-426c-bde4-9852b2025dfc",
"metadata": {},
"source": [
"This behavior is what we expect.\n",
"Numbers and strings are *immutable* types in Python.\n",
"\n",
"What happens, though, when we try a similar example with a *mutable* type, like a list?\n",
"Here, `b` is assigned the initial value of `a`, a list."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "40278617-334f-4bfc-8b72-b0e9a73d3e5f",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"a = [x, y]\n",
"b = a"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8f561d59-1509-49cb-ba39-923af86b3b7a",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"a"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cf8c8b8e-a89b-4696-a3cd-34467f631465",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"b"
]
},
{
"cell_type": "markdown",
"id": "4744a1bb-8ae0-489c-92e1-f875fa6c80ad",
"metadata": {},
"source": [
"Now change an element of `a`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6b29d385-64a9-47a2-8d1d-adb6678d907b",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"a[-1] = \"CSDMS\"\n",
"a"
]
},
{
"cell_type": "markdown",
"id": "7585e2ab-f88c-4232-a47a-010c3684e093",
"metadata": {},
"source": [
"Does `b` change?"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5013f5ed-3caa-418e-84d4-9d9864e1937b",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"b"
]
},
{
"cell_type": "markdown",
"id": "7ffbfcad-4c73-4007-a46e-830c13e094fb",
"metadata": {},
"source": [
"This behavior holds for all mutable objects,\n",
"like lists, dictionaries, and, as we'll see, NumPy arrays.\n",
"\n",
"Most mutable types, including lists, have a `copy` method,\n",
"which returns a shallow copy of an object.\n",
"Redo the example above using the `copy` method."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "69b54be9-6549-4437-a955-236b78458e4d",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"c = [x, y]\n",
"d = c.copy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "aab94af2-88f4-4ae9-9196-d22da6f1a5e5",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"c"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c4293a2-c1f3-47d8-ae20-01d16de8a5df",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"d"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "63700f10-5c03-49f5-be9e-39544af8a37c",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"c[-1] = \"CSDMS\"\n",
"c"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a0bc5b39-7c9a-4c62-9bcd-d7d15efb2f49",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"d"
]
},
{
"cell_type": "markdown",
"id": "014fd21b",
Expand All @@ -432,7 +706,11 @@
"The official Python tutorial contains more information on the topics covered in this notebook:\n",
"* [loops](https://docs.python.org/3/tutorial/controlflow.html#for-statements)\n",
"* [conditionals](https://docs.python.org/3/tutorial/controlflow.html#if-statements)\n",
"* [exceptions and the `try` statement](https://docs.python.org/3/tutorial/errors.html)"
"* [exceptions and the `try` statement](https://docs.python.org/3/tutorial/errors.html)\n",
"\n",
"More information on reference copying:\n",
"* The [*copy* module](https://docs.python.org/3/library/copy.html) provides methods for shallow (objects only) and deep (objects containing objects) copies of mutable objects.\n",
"* An extensive [tutorial lesson](https://python-course.eu/python-tutorial/shallow-and-deep-copy.php) on copying mutable objects"
]
}
],
Expand Down

0 comments on commit d69d070

Please sign in to comment.