{"id":"lists-items","slug":"items","title":"Lists and indexes","text":"Think of a program that keeps a week of temperatures. With what you know now, it would need seven variables, `monday` to `sunday`, and a program that reads values until the user stops couldn't work at all, because it can't make up new variable names as it runs. A **list** solves both problems: it keeps any number of values under one name. You write it in square brackets, with commas between the values:\n\n```python\ntemperatures = [18, 21, 17, 25]  # a list of four numbers\nnames = [\"Ada\", \"Linus\", \"Grace\"]\nempty = []\nprint(temperatures)\nprint(names)\nprint(empty)\n```\n\n```output\n[18, 21, 17, 25]\n['Ada', 'Linus', 'Grace']\n[]\n```\n\nThe values in a list are its **items** (or elements). `[]` is an empty list, with no items yet. When you print a list, Python shows it the way you would write it in code, so strings in a list are shown with quotes, as in the interpreter.\n\n### Indexes\n\nEach item has an **index**, its place in the list. As with the characters of a string, the first index is 0, and `-1` is the last item:\n\n```python\ntemperatures = [18, 21, 17, 25]\nprint(temperatures[0])\nprint(temperatures[2])\nprint(temperatures[-1])\nprint(\"Change from first to last:\", temperatures[-1] - temperatures[0])\n```\n\n```output\n18\n17\n25\nChange from first to last: 7\n```\n\nThe function `len` gives the number of items, so the last index is `len(temperatures) - 1`. An index past the end stops the program:\n\n```python\ntemperatures = [18, 21, 17, 25]\nprint(len(temperatures))\nprint(temperatures[4])\n```\n\n```output\n4\n```\n\n```crash\nTraceback (most recent call last):\n  File \"main.py\", line 3, in <module>\n    print(temperatures[4])\n          ~~~~~~~~~~~~^^^\nIndexError: list index out of range\n```\n\nThe list has 4 items, at indexes 0 to 3. Index 4 would be a fifth item, which doesn't exist.\n\n### Changing an item\n\nUnlike a string, a list can be changed after it's made. Give an item a new value as you would give a variable one:\n\n```python\ntemperatures = [18, 21, 17, 25]\ntemperatures[2] = 19\ntemperatures[0] = temperatures[0] + 1\nprint(temperatures)\n```\n\n```output\n[19, 21, 19, 25]\n```\n\nThe other items stay as they were. An index in square brackets on the left of `=` says which item gets the new value.\n","task":"Fill in the blanks so the program prints the number of planets in the list, the first planet, and then the list with `Earth` renamed to `Terra`:\n\n```\nPlanets: 4\nClosest to the sun: Mercury\n['Mercury', 'Venus', 'Terra', 'Mars']\n```\n","kind":"fill","seed":"planets = [\"Mercury\", \"Venus\", \"Earth\", \"Mars\"]\nprint(\"Planets:\", [[len]](planets))\nprint(\"Closest to the sun:\", planets[[[0]]])\nplanets[[[2‖-2]]] = \"Terra\"\nprint(planets)\n","solution":"planets = [\"Mercury\", \"Venus\", \"Earth\", \"Mars\"]\nprint(\"Planets:\", len(planets))\nprint(\"Closest to the sun:\", planets[0])\nplanets[2] = \"Terra\"\nprint(planets)\n","hints":["The function that counts the items of a list is the same one that counts the characters of a string.","The first item is at index 0. Count from 0 to find the index of `\"Earth\"`.","`len(planets)` is 4, the first planet is `planets[0]`, and `Earth` is at index 2."],"tests":[{"name":"Output","stdin":"","expect":"Planets: 4\nClosest to the sun: Mercury\n['Mercury', 'Venus', 'Terra', 'Mars']","hidden":false}],"require":[],"forbid":[],"more":[{"task":"What does this program print? Type each line it prints.\n","kind":"predict","seed":"numbers = [4, 8, 15, 16, 23]\nprint(numbers[1])\nprint(numbers[-1])\nnumbers[0] = numbers[3] + 1\nprint(numbers[0])\nprint(len(numbers))\nprint(numbers)\n","solution":"numbers = [4, 8, 15, 16, 23]\nprint(numbers[1])\nprint(numbers[-1])\nnumbers[0] = numbers[3] + 1\nprint(numbers[0])\nprint(len(numbers))\nprint(numbers)\n","hints":["Indexes start at 0, so `numbers[1]` is the second item. Index -1 is the last item.","`numbers[3]` is 16, so the first item becomes 17.","Changing an item doesn't change the length of the list."],"tests":[{"name":"Output","stdin":"","expect":"8\n23\n17\n5\n[17, 8, 15, 16, 23]","hidden":false}],"require":[],"forbid":[],"lines":["8","23","17","5","[17, 8, 15, 16, 23]"]},{"task":"A house has the rooms in the list `rooms`, numbered from 1. Write a program that asks for a room number and prints that room's name. A number with no room prints `No such room`:\n\n```\nRoom number: 2\nRoom 2 is the kitchen\n```\n","kind":"code","seed":"rooms = [\"hall\", \"kitchen\", \"library\", \"attic\"]\n","solution":"rooms = [\"hall\", \"kitchen\", \"library\", \"attic\"]\nnumber = int(input(\"Room number: \"))\nif 1 <= number <= len(rooms):\n    print(f\"Room {number} is the {rooms[number - 1]}\")\nelse:\n    print(\"No such room\")\n","hints":["Room 1 is at index 0, so room `number` is at index `number - 1`.","The room numbers go from 1 to `len(rooms)`. Check that the number is in that range before you use it as an index.","`if 1 <= number <= len(rooms):` prints the room with an f-string, and `else:` prints `No such room`."],"tests":[{"name":"Test 1","stdin":"2\n","expect":"Room number: 2\nRoom 2 is the kitchen","hidden":false},{"name":"Test 2","stdin":"4\n","expect":"Room number: 4\nRoom 4 is the attic","hidden":true},{"name":"Test 3","stdin":"1\n","expect":"Room number: 1\nRoom 1 is the hall","hidden":true},{"name":"Test 4","stdin":"0\n","expect":"Room number: 0\nNo such room","hidden":true},{"name":"Test 5","stdin":"5\n","expect":"Room number: 5\nNo such room","hidden":true}],"require":[],"forbid":[{"pattern":"<=\\s*4\\b|<\\s*5\\b","message":"Use `len(rooms)` instead of the number 4, so the program still works if a room is added."}]}]}