{"course":{"slug":"python-for-ai","title":"Python, from Zero, for AI","url":"https://addaly.com/learn/python-for-ai","level":"beginner","track":"build"},"lesson":{"slug":"loops","title":"Loops, or doing the same thing to many things","url":"https://addaly.com/learn/python-for-ai/loops","position":16,"of":89,"minutes":6,"answer":"Indentation decides what repeats, so where you start the running total decides whether the answer is a sum.","keyIdea":"Indentation decides what repeats, so where you start the running total decides whether the answer is a sum."},"body":{"format":"markdown","text":"## Repeat once per item\n\n```python\nprices = [120, 340, 90, 75]\n\nfor price in prices:\n    print(price)\n```\n\nRead it as an English sentence: for each price in prices, print the price. Python takes the first item, attaches the name `price` to it, runs the indented block, then takes the second item, and so on until the list runs out.\n\n`price` is a name you chose. It could be `p` or `amount`. It only exists because you named it in the `for` line, and it gets re-attached to a new value on every pass.\n\n## The indentation is the loop body\n\nPython uses indentation the way other languages use braces. Whatever is indented under the `for` line runs every pass. Whatever is not, runs once, after the loop is done.\n\n```python\nfor price in prices:\n    print(\"item\", price)\nprint(\"done\")\n```\n\n`done` prints once. Move it four spaces to the right and it prints four times. Use four spaces, be consistent, and let your editor do it for you. Mixing tabs and spaces produces `IndentationError` or, worse, code that runs and means something you did not intend.\n\n## The accumulator\n\nThe most useful pattern in beginner programming: start with an empty answer, add to it on every pass, look at it at the end.\n\n```python\nprices = [120, 340, 90, 75]\n\ntotal = 0\nfor price in prices:\n    total = total + price\nprint(total)     # 625\n```\n\nThe line `total = 0` is outside the loop, and this is the whole trick. It has to happen once, before any adding starts. Put it inside the loop and it happens on every pass, wiping out the running total each time, and the answer becomes the last item instead of the sum. That bug produces no error and looks almost identical on screen.\n\n`total = total + price` can be shortened to `total += price`. Same thing.\n\nThe same pattern builds lists:\n\n```python\ndoubled = []\nfor price in prices:\n    doubled.append(price * 2)\nprint(doubled)   # [240, 680, 180, 150]\n```\n\n## Counting with range\n\nWhen you want to do something a fixed number of times rather than once per item:\n\n```python\nfor i in range(3):\n    print(\"attempt\", i)\n```\n\n```\nattempt 0\nattempt 1\nattempt 2\n```\n\n`range(3)` gives 0, 1, 2. Three numbers, starting at zero, stopping before three. `range(1, 4)` gives 1, 2, 3. The stop value is never included, which is deliberate: `range(len(prices))` then lines up exactly with the valid positions.\n\n## Looping over a dict\n\n```python\nstudent = {\"name\": \"Amara\", \"city\": \"Kano\", \"marks\": 81}\n\nfor key in student:\n    print(key, \"->\", student[key])\n\nfor key, value in student.items():\n    print(key, \"->\", value)\n```\n\nBoth print the same thing. `.items()` hands you the key and the value together, which is usually what you wanted.\n\n## while, for when you do not know how many\n\n```python\nbalance = 5000\nmonths = 0\nwhile balance > 0:\n    balance = balance - 1200\n    months = months + 1\nprint(months, \"months\")   # 5 months\n```\n\n`while` repeats as long as its condition is true, and checks the condition before each pass. If nothing inside ever makes the condition false, the program runs forever; press Ctrl+C to stop it. Reach for `for` first. Use `while` when the number of passes depends on what happens inside.\n\n## Try this now\n\n```python\nmarks = [78, 81, 45, 92, 60]\n\npassed = []\nfor m in marks:\n    if m >= 50:\n        passed.append(m)\n\nprint(passed)\nprint(f\"{len(passed)} of {len(marks)} passed\")\nprint(f\"average {sum(marks) / len(marks)}\")\n```"},"check":{"question":"A program is `prices = [120, 340, 90]`, then a `for price in prices:` loop whose indented body is `total = 0` followed by `total = total + price`, then an unindented `print(total)`. What is printed?","options":[{"text":"`550`, because the additions still happen on every pass and the indentation only affects layout.","correct":false,"tempting":"Every price really does get added at some point, so it feels as though the additions must accumulate into the same running total."},{"text":"`0`, because the loop's last action was setting `total` to zero.","correct":false,"tempting":"`total = 0` is the eye-catching line inside the loop, and it is easy to picture it as the final thing that happened."},{"text":"`90`, because `total` is reset to zero at the top of every pass, so only the last price survives.","correct":true},{"text":"An error, because `total` was created inside the loop and does not exist on the line after it.","correct":false,"tempting":"In several other languages a name created inside a block really is gone once the block ends, so this is a well-earned habit from elsewhere."}]},"prev":{"slug":"dict-patterns","title":"Dictionary patterns: defaults, counting and grouping","url":"https://addaly.com/learn/python-for-ai/dict-patterns"},"next":{"slug":"while-loops-and-control","title":"While loops, break, and the loop that never ends","url":"https://addaly.com/learn/python-for-ai/while-loops-and-control"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Loops, or doing the same thing to many things', in Python, from Zero, for AI. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/python-for-ai/loops (Accessed: 31 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Loops, or doing the same thing to many things","courseTitle":"Python, from Zero, for AI","module":{"index":2,"slug":"collections-and-loops","title":"Collections, loops, and the shape of your data"},"answer":null,"keyIdea":"Indentation decides what repeats, so where you start the running total decides whether the answer is a sum.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"repeat-once-per-item","runs":[{"text":"Repeat once per item"}]},{"t":"code","lang":"python","label":"Python","text":"prices = [120, 340, 90, 75]\n\nfor price in prices:\n    print(price)"},{"t":"p","runs":[{"text":"Read it as an English sentence: for each price in prices, print the price. Python takes the first item, attaches the name "},{"text":"price","code":true},{"text":" to it, runs the indented block, then takes the second item, and so on until the list runs out."}]},{"t":"p","runs":[{"text":"price","code":true},{"text":" is a name you chose. It could be "},{"text":"p","code":true},{"text":" or "},{"text":"amount","code":true},{"text":". It only exists because you named it in the "},{"text":"for","code":true},{"text":" line, and it gets re-attached to a new value on every pass."}]},{"t":"h2","id":"the-indentation-is-the-loop-body","runs":[{"text":"The indentation is the loop body"}]},{"t":"p","runs":[{"text":"Python uses indentation the way other languages use braces. Whatever is indented under the "},{"text":"for","code":true},{"text":" line runs every pass. Whatever is not, runs once, after the loop is done."}]},{"t":"code","lang":"python","label":"Python","text":"for price in prices:\n    print(\"item\", price)\nprint(\"done\")"},{"t":"p","runs":[{"text":"done","code":true},{"text":" prints once. Move it four spaces to the right and it prints four times. Use four spaces, be consistent, and let your editor do it for you. Mixing tabs and spaces produces "},{"text":"IndentationError","code":true},{"text":" or, worse, code that runs and means something you did not intend."}]},{"t":"h2","id":"the-accumulator","runs":[{"text":"The accumulator"}]},{"t":"p","runs":[{"text":"The most useful pattern in beginner programming: start with an empty answer, add to it on every pass, look at it at the end."}]},{"t":"code","lang":"python","label":"Python","text":"prices = [120, 340, 90, 75]\n\ntotal = 0\nfor price in prices:\n    total = total + price\nprint(total)     # 625"},{"t":"p","runs":[{"text":"The line "},{"text":"total = 0","code":true},{"text":" is outside the loop, and this is the whole trick. It has to happen once, before any adding starts. Put it inside the loop and it happens on every pass, wiping out the running total each time, and the answer becomes the last item instead of the sum. That bug produces no error and looks almost identical on screen."}]},{"t":"p","runs":[{"text":"total = total + price","code":true},{"text":" can be shortened to "},{"text":"total += price","code":true},{"text":". Same thing."}]},{"t":"p","runs":[{"text":"The same pattern builds lists:"}]},{"t":"code","lang":"python","label":"Python","text":"doubled = []\nfor price in prices:\n    doubled.append(price * 2)\nprint(doubled)   # [240, 680, 180, 150]"},{"t":"h2","id":"counting-with-range","runs":[{"text":"Counting with range"}]},{"t":"p","runs":[{"text":"When you want to do something a fixed number of times rather than once per item:"}]},{"t":"code","lang":"python","label":"Python","text":"for i in range(3):\n    print(\"attempt\", i)"},{"t":"code","lang":"","label":"Text","text":"attempt 0\nattempt 1\nattempt 2"},{"t":"p","runs":[{"text":"range(3)","code":true},{"text":" gives 0, 1, 2. Three numbers, starting at zero, stopping before three. "},{"text":"range(1, 4)","code":true},{"text":" gives 1, 2, 3. The stop value is never included, which is deliberate: "},{"text":"range(len(prices))","code":true},{"text":" then lines up exactly with the valid positions."}]},{"t":"h2","id":"looping-over-a-dict","runs":[{"text":"Looping over a dict"}]},{"t":"code","lang":"python","label":"Python","text":"student = {\"name\": \"Amara\", \"city\": \"Kano\", \"marks\": 81}\n\nfor key in student:\n    print(key, \"->\", student[key])\n\nfor key, value in student.items():\n    print(key, \"->\", value)"},{"t":"p","runs":[{"text":"Both print the same thing. "},{"text":".items()","code":true},{"text":" hands you the key and the value together, which is usually what you wanted."}]},{"t":"h2","id":"while-for-when-you-do-not-know-how-many","runs":[{"text":"while, for when you do not know how many"}]},{"t":"code","lang":"python","label":"Python","text":"balance = 5000\nmonths = 0\nwhile balance > 0:\n    balance = balance - 1200\n    months = months + 1\nprint(months, \"months\")   # 5 months"},{"t":"p","runs":[{"text":"while","code":true},{"text":" repeats as long as its condition is true, and checks the condition before each pass. If nothing inside ever makes the condition false, the program runs forever; press Ctrl+C to stop it. Reach for "},{"text":"for","code":true},{"text":" first. Use "},{"text":"while","code":true},{"text":" when the number of passes depends on what happens inside."}]},{"t":"h2","id":"try-this-now","runs":[{"text":"Try this now"}],"role":"try"},{"t":"code","lang":"python","label":"Python","text":"marks = [78, 81, 45, 92, 60]\n\npassed = []\nfor m in marks:\n    if m >= 50:\n        passed.append(m)\n\nprint(passed)\nprint(f\"{len(passed)} of {len(marks)} passed\")\nprint(f\"average {sum(marks) / len(marks)}\")"}],"check":{"question":[{"text":"A program is "},{"text":"prices = [120, 340, 90]","code":true},{"text":", then a "},{"text":"for price in prices:","code":true},{"text":" loop whose indented body is "},{"text":"total = 0","code":true},{"text":" followed by "},{"text":"total = total + price","code":true},{"text":", then an unindented "},{"text":"print(total)","code":true},{"text":". What is printed?"}],"options":[{"text":[{"text":"550","code":true},{"text":", because the additions still happen on every pass and the indentation only affects layout."}],"correct":false,"tempting":[{"text":"Every price really does get added at some point, so it feels as though the additions must accumulate into the same running total."}]},{"text":[{"text":"0","code":true},{"text":", because the loop’s last action was setting "},{"text":"total","code":true},{"text":" to zero."}],"correct":false,"tempting":[{"text":"total = 0","code":true},{"text":" is the eye-catching line inside the loop, and it is easy to picture it as the final thing that happened."}]},{"text":[{"text":"90","code":true},{"text":", because "},{"text":"total","code":true},{"text":" is reset to zero at the top of every pass, so only the last price survives."}],"correct":true,"tempting":null},{"text":[{"text":"An error, because "},{"text":"total","code":true},{"text":" was created inside the loop and does not exist on the line after it."}],"correct":false,"tempting":[{"text":"In several other languages a name created inside a block really is gone once the block ends, so this is a well-earned habit from elsewhere."}]}],"order":[3,2,1,0],"why":null},"prev":{"slug":"dict-patterns","title":"Dictionary patterns: defaults, counting and grouping","minutes":8},"next":{"slug":"while-loops-and-control","title":"While loops, break, and the loop that never ends","minutes":7}}}