{"assignment":{"_schema_version":2,"course_id":37,"date_created":"2022-06-28T19:00:00+00:00","date_modified":"2023-09-10T14:14:20.295464+00:00","extra_instructor_files":"","extra_starting_files":"","forked_id":null,"forked_version":null,"hidden":false,"id":1089,"instructions":"## Lists and Indexes\n\n```python list-elements\nvalues = [10, 10, 20,  1,  5]\n#indexes:  0,  1,  2,  3,  4\n#   also: -5, -4, -3, -2, -1\n\nprint(\"First is\", values[0])\nprint(\"Third is\", values[2])\nprint(\"Last is\", values[-1])\n```\n\nSo far, we have iterated through a list using the for-each syntax to get each value of the list.\nWe have also used indexing to access specific values in a list by their individual position.\nIn many languages, indexes are used to iterate through all the values of a list.\nThe index of the list are the integers\u2014starting from 0 and counting up\u2014that uniquely identify each element.\nThe code shown here demonstrates how we can access indexes using positive and negative integers.\nIn this lesson, we'll learn how we can use indexes to iterate through the list, modify elements of the list, and do more complex manipulations to the list.\n\n## Value Iteration vs. Index Iteration\n\n```python index-value-iteration\nnames = [\"Adam\", \"Betty\", \"Clarice\"]\n    \n# Value style\nfor name in names:\n    print(name)\n\n# Index style\nfor index in range(len(names)):\n    print(index, names[index])\n```\n\nThe top part of the following code is the usual way to process a list in Python: by iterating through each value.\nHowever, you can also iterate by using a combination of the `range` and `len` functions as shown in the example here.\nBoth the value style and the index style can print the values, but the index style also gives us the index.\n\nThe index style iteration will create a variable named `index` that stores the index for each value.\nSo, the loop iterations will print `0 Adam`, `1 Betty`, and `2 Clarice`.\nThe index style relies on two helper functions that need further explanation.\n\n## Len Function\n\n```python len-function\ngrocery_list = ['Bread', 'Ham', 'Eggs']\n\n# len function\nnumber_of_groceries = len(grocery_list)\nprint(\"Length of list is\", number_of_groceries)\nprint(\"The length of Bread is\", len(grocery_list[0]))\n```\n\nThe `len` function is relatively straightforward; the function consumes an iterable (like a list) and produces an integer representing the length of the list.\nIn other words, the number of elements in the list.\nThe `len` function also works on strings, producing the number of characters in the string.\nIn fact, the `len` function does all the work of the basic count pattern, although sometimes we want to extend that pattern in ways that you cannot with the `len` function (for example, to filter at the same time).\n\n## Range Function\n\n```python range-function\nnumbers = range(3)\nfor number in numbers:\n    print(\"Number: \", number)\n  \n# Range with Map pattern\nchapters = []\nfor number in range(10):\n    chapters.append(\"Chapter \" + str(number))\nprint(chapters)\n```\n\nThe `range` function consumes an integer and produces a sequence of integers from 0 up to that number (but not including that number).\nOne use case is to iterate an explicit number of times, as in the first example, where we iterate exactly three times.\nA distinct use case for this is to create lists of numbers via the map pattern as shown in the second half of the code.\nIn that example, we iterate 10 times to produce a list of 10 numbers starting from `\"Chapter 0\"` to `\"Chapter 9\"`.\n\n## Generators\n\n```python weird-generators\nprint(range(5))\n# range(0, 5)\n\nprint(list(range(5)))\n# [0, 1, 2, 3, 4]\n```\n\nIt's important to note that the `range` function does not technically return a list of integers.\nInstead, the generator returns a special type that is like a list, called a generator.\nFor the most part, you will not be able to tell the difference between a range generator and a regular list.\nHowever, they are slightly different types if you inspect them closely.\nYou can convert a generator into a list using the built-in `list` function, but this will usually be unnecessary.\nFor now, do not worry about the difference.\n\n## Enumerate Function\n\n```python enumerate-function\ngrocery_list = ['Bread', 'Ham', 'Eggs']\n\nfor index, grocery in enumerate(grocery_list):\n    print(\"At index\", index, \"there is\", grocery)\n```\n\nAs an alternative to combining `range` and `len`, we can also use the `enumerate` function.\nThe `enumerate` function allows us to access both the values and indexes at the same time.\nWhile this is convenient, we do have a new, unusual feature to learn about.\nInstead of one iteration variable, we now have two iteration variables to worry about.\nThis only works because the `enumerate` function returns a list of pairs of things.\n\n## Modifying Elements of a List with Indexes\n\n```python modifying-list-elements\nnames = [\"Adam\", \"Betty\", \"Clarice\"]\n\nnames[0] = \"Alphonse\"\nnames[-1] = \"Carol\"\nprint(names)\n\n# 1) But indexing out of bounds will NOT work!\n#names[3] = \"David\"\n# 2) Nor will modifying a string's characters\n#a_name = \"Erin\"\n#a_name[0] = \"B\"\n```\n\nSo far, we have focused on only one way to modify a list, using the `append` and `pop` methods to add and remove elements from the end of the list.\nBut, we can also update the elements of a list using assignment statements, like how we can update fields of dataclasses.\nAs this example code demonstrates, we just put the indexed element on the left-hand side of the assignment statement and the appropriate indexes value will be changed.\nNote also that the first commented-out block of code demonstrates that we cannot use this to add new elements to the list.\nIf you attempt to update an index outside of the size of the list, you'll get an IndexError.\nNote also the last example shown in the commented-out code where we try to modify the first character of a string.\nThat does not work and will cause an error because strings are immutable.\n\n## Modifying Multiple Elements with Iteration\n\n```python modifying-for-loop\nwords = [\"Dog\", \"Cat\", \"Mouse\"]\n\nfor index, word in enumerate(words):\n    words[index] = word + \"s\"\n\nprint(words)\n```\n\nUp until now, our `for` loops have always created new lists instead of directly modifying old lists.\nThis is because modifying values makes it difficult to keep track of changes.\nBut, sometimes, we will want to modify every element of our original list.\nBy combining the `enumerate` function and the index assignment syntax we just learned, we can do so.\nThis code will add the letter `s` to the end of each word in the original list and then assign to that index in the list.\n\n## Why Modify Lists?\n\n```python modify-or-copy\noriginal = [1, 2, 3]\ncopied = []\n\nfor index, value in enumerate(original):\n    # Copy original\n    copied.append(value)\n    # Modify original\n    original[index] = value + 1\n\nprint(original)\nprint(copied)\n```\n\nThe major advantage of modifying an existing list instead of creating a new one with the map pattern is that less memory is required.\nAfter all, creating a copy of a list means creating a second list of the same size.\nIf we were dealing with truly massive lists, we might want to avoid this.\nHowever, there are serious advantages to not messing up the original list.\nIt makes it much easier to think about other parts of large programs if you know that a list will never be modified by a helper function.\nOtherwise, you may be surprised to find that a list has been changed out from under you in another part of the program.\nBut, given the tradeoff, how do you know if a list is big enough to justify mutation instead of copying? Usually, you won't need to know until you run out of memory, so it is not worth worrying about in advance.\nWe rarely mutate lists in Python.\n\n## Swapping Elements\n\n```python swap-example\nwords = [\"Dog\", \"Cat\", \"Mouse\"]\nprint(words)\n\n# Swap two elements\nwords[0], words[1] = [words[1], words[0]]\nprint(words)\n```\n\nSometimes, you will need to swap the position of two elements in a list.\nTo do so, we need to assign directly to multiple indices at once.\nThis is also how we can assign two iteration variables at once when we use the `enumerate` function.\nPython always handles the right-hand side of the assignment statement first, so the original values are obtained and put into a new list.\nThen, those values are assigned one at a time to the two entries on the left-hand side, which are the first and second indexes of the list.\nBy assigning it to the index, we update the value stored at that location.\n\n## Unpacking a List\n\n```python list-unpack\nwords = [\"Dog\", \"Cat\", \"Mouse\"]\nprint(words)\n\n# Unpack a list\nfirst, second, third = words\nprint(\"Second animal is:\", second)\n```\n\nIn this code, we assign multiple variables at once.\nThis is called \"unpacking\" and allows us to turn a list into individual variables.\nHowever, this only works if we know that there are exactly three elements in the list.\nWe do not usually know the exact length of a list, so we will not need to take advantage of this syntax very often.\nStill, sometimes it is convenient to be able to assign names to the values at specific indexes in a list.\n\n## Indexes vs. Values\n\n1. Indexes allow more flexibility\n2. Values require fewer operations\n3. Values are less complex\n\nSo, when do you use indexes and when do you use values? Usually, you should stick to value style unless you have an explicit reason to use indexes.\nIndexes allow more flexibility and are necessary for certain kinds of specialized algorithms.\nHowever, they require more operations and are more complex to reason about.\nWhen you manipulate indexes, you run the risks of mutable danger, which we discussed a few chapters ago.\nIn general, we prefer to read data and create new variables instead of modifying existing values.\nThat way, we do not have to keep track of whether data has changed later in the program.\n\n## Summary\n\n- A `for` loop can iterate over the values in a list but can also iterate over the indices in a list.\n- Index iteration requires either the combination of the `range` and `len` functions or the `enumerate` function.\n  - The `len` function consumes a list and produces an integer representing the size of the list.\n  - The `range` function consumes an integer and produces a sequence of integers from 0 to the given integer.\n  - The `enumerate` function consumes a list and produces a sequence of pairs of indexes and values from a given list.\n- You can change the value at a specific index of a list using assignment syntax where the left-hand side is a list with an index.\n- You can change all the values in a list using index iteration and assignment statements.\n- You can swap the values of two indexes using list unpacking and multiple assignments.\n- You can assign more than one variable at a time using multiple assignments.\n- Index iteration allows more flexibility and control while value iteration is simpler and requires fewer operations.\n\n","ip_ranges":"","name":"7A1) Lists and Indexes Reading","on_change":"","on_eval":"","on_run":"","owner_id":1,"owner_id__email":"acbart@udel.edu","points":0,"public":true,"reviewed":false,"sample_submissions":[],"settings":"{\n  \"header\": \"Lists and Indexes\",\n  \"youtube\": {\n    \"Bart\": \"3iUPQl9XIZU\",\n    \"Amy\": \"GdJt-L55cLU\"\n  },\n  \"summary\": \"\",\n  \"small_layout\": true,\n  \"video\": {\n    \"Bart\": \"https://blockpy.cis.udel.edu/videos/bakery_sequences_indexes-Bart.mp4\",\n    \"Amy\": \"https://blockpy.cis.udel.edu/videos/bakery_sequences_indexes-Amy.mp4\"\n  }\n}","starting_code":"","subordinate":true,"tags":[],"type":"reading","url":"bakery_sequences_indexes_read","version":8},"ip":"216.73.216.157","submission":{"_schema_version":3,"assignment_id":1089,"assignment_version":8,"attempts":0,"code":"","correct":false,"course_id":37,"date_created":"2026-05-20T14:01:49.850063+00:00","date_due":"","date_graded":"","date_locked":"","date_modified":"2026-05-20T14:01:49.850063+00:00","date_started":"","date_submitted":"","endpoint":"","extra_files":"","feedback":"","grading_status":"NotReady","id":2036920,"score":0.0,"submission_status":"Started","time_limit":"","url":"submission_url-8ffa76a8-1a48-4e1a-bd7b-d5c2a45b1199","user_id":2044668,"user_id__email":"","version":0},"success":true}
