{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [], "authorship_tag": "ABX9TyOeer9+GPbzwQfl+cK5VnZM", "include_colab_link": true }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "view-in-github", "colab_type": "text" }, "source": [ "\"Open" ] }, { "cell_type": "markdown", "source": [ "# In Python, **an iterator** is an object that implements the iterator protocol. This protocol consists of two special methods:\n", "__iter__(): This method returns the iterator object itself. It allows an object to be treated as an iterator.\n", "__next__(): This method returns the next item from the iterator. When there are no more items to return, it raises a StopIteration exception.\n", "Key Characteristics and Usage:\n", "Sequential Traversal: Iterators enable sequential traversal through elements of a collection (like lists, tuples, strings, dictionaries, sets).\n", "Memory Efficiency: They are memory-efficient because they yield elements one at a time, rather than loading the entire collection into memory at once. This is particularly beneficial for large datasets.\n", "iter() and next() Functions:\n", "The built-in iter() function takes an iterable object (e.g., a list) and returns an iterator object.\n", "The built-in next() function takes an iterator object and retrieves the next item.\n", "for Loops: Python's for loops implicitly use iterators. When you iterate over an iterable with a for loop, Python internally converts it into an iterator and repeatedly calls next() until StopIteration is raised.\n", "Generators: Generators are a convenient way to create iterators using functions that contain the yield keyword. A generator function returns a generator object, which is a type of iterator." ], "metadata": { "id": "R_rl--VusQUB" } }, { "cell_type": "code", "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "QzYjeKyQsO1Q", "outputId": "1fa596bc-8927-48e3-ca29-0cfc0bb46c04" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "1\n", "2\n", "3\n", "4\n", "apple\n", "banana\n", "cherry\n", "b\n", "a\n", "n\n", "a\n", "n\n", "a\n", "apple\n", "banana\n", "cherry\n", "b\n", "a\n", "n\n", "a\n", "n\n", "a\n", "1\n", "2\n", "3\n", "4\n", "5\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "11\n", "12\n", "13\n", "14\n", "15\n", "16\n", "17\n", "18\n", "19\n", "20\n", "G\n", "F\n", "G\n", "2\n", "4\n", "6\n", "8\n", "10\n", "100\n", "200\n", "300\n", "End of iteration\n", "1\n", "2\n", "3\n", "4\n", "7\n", "0\n", "4\n", "7\n", "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "1\n", "1\n", "2\n", "3\n", "4\n", "5\n", "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "# An iterable (a list)\n", "my_list = [1, 2, 3, 4]\n", "\n", "# Get an iterator from the iterable\n", "my_iterator = iter(my_list)\n", "\n", "# Use next() to get elements one by one\n", "print(next(my_iterator)) # Output: 1\n", "print(next(my_iterator)) # Output: 2\n", "\n", "# Iterators can also be used directly in a for loop\n", "for item in my_iterator:\n", " print(item) # Output: 3, then 4\n", "\n", "mytuple = (\"apple\", \"banana\", \"cherry\")\n", "myit = iter(mytuple)\n", "\n", "print(next(myit))\n", "print(next(myit))\n", "print(next(myit))\n", "\n", "mystr = \"banana\"\n", "myit = iter(mystr)\n", "\n", "print(next(myit))\n", "print(next(myit))\n", "print(next(myit))\n", "print(next(myit))\n", "print(next(myit))\n", "print(next(myit))\n", "\n", "mytuple = (\"apple\", \"banana\", \"cherry\")\n", "\n", "for x in mytuple:\n", " print(x)\n", "\n", "mystr = \"banana\"\n", "\n", "for x in mystr:\n", " print(x)\n", "class MyNumbers:\n", " def __iter__(self):\n", " self.a = 1\n", " return self\n", "\n", " def __next__(self):\n", " x = self.a\n", " self.a += 1\n", " return x\n", "\n", "myclass = MyNumbers()\n", "myiter = iter(myclass)\n", "\n", "print(next(myiter))\n", "print(next(myiter))\n", "print(next(myiter))\n", "print(next(myiter))\n", "print(next(myiter))\n", "\n", "class MyNumbers:\n", " def __iter__(self):\n", " self.a = 1\n", " return self\n", "\n", " def __next__(self):\n", " if self.a <= 20:\n", " x = self.a\n", " self.a += 1\n", " return x\n", " else:\n", " raise StopIteration\n", "\n", "myclass = MyNumbers()\n", "myiter = iter(myclass)\n", "\n", "for x in myiter:\n", " print(x)\n", "\n", "s = \"GFG\"\n", "it = iter(s)\n", "\n", "print(next(it))\n", "print(next(it))\n", "print(next(it))\n", "\n", "class EvenNumbers:\n", " def __iter__(self):\n", " self.n = 2 # Start from the first even number\n", " return self\n", "\n", " def __next__(self):\n", " x = self.n\n", " self.n += 2 # Increment by 2 to get the next even number\n", " return x\n", "\n", "# Create an instance of EvenNumbers\n", "even = EvenNumbers()\n", "it = iter(even)\n", "\n", "# Print the first five even numbers\n", "print(next(it))\n", "print(next(it))\n", "print(next(it))\n", "print(next(it))\n", "print(next(it))\n", "\n", "li = [100, 200, 300]\n", "it = iter(li)\n", "\n", "# Iterate until StopIteration is raised\n", "while True:\n", " try:\n", " print(next(it))\n", " except StopIteration:\n", " print(\"End of iteration\")\n", " break\n", "\n", "# Iterable: list\n", "numbers = [1, 2, 3]\n", "\n", "# Iterator: created using iter()\n", "it = iter(numbers)\n", "print(next(it))\n", "print(next(it))\n", "print(next(it))\n", "\n", "\n", "# define a list\n", "my_list = [4, 7, 0]\n", "\n", "# create an iterator from the list\n", "iterator = iter(my_list)\n", "\n", "# get the first element of the iterator\n", "print(next(iterator)) # prints 4\n", "\n", "# get the second element of the iterator\n", "print(next(iterator)) # prints 7\n", "\n", "# get the third element of the iterator\n", "print(next(iterator)) # prints 0\n", "\n", "# define a list\n", "my_list = [4, 7, 0]\n", "\n", "for element in my_list:\n", " print(element)\n", "\n", "\n", "# create a list of integers\n", "my_list = [1, 2, 3, 4, 5]\n", "\n", "# create an iterator from the list\n", "iterator = iter(my_list)\n", "\n", "# iterate through the elements of the iterator\n", "for element in iterator:\n", "\n", " # Print each element\n", " print(element)\n", "\n", "class PowTwo:\n", " \"\"\"Class to implement an iterator\n", " of powers of two\"\"\"\n", "\n", " def __init__(self, max=0):\n", " self.max = max\n", "\n", " def __iter__(self):\n", " self.n = 0\n", " return self\n", "\n", " def __next__(self):\n", " if self.n <= self.max:\n", " result = 2 ** self.n\n", " self.n += 1\n", " return result\n", " else:\n", " raise StopIteration\n", "\n", "\n", "# create an object\n", "numbers = PowTwo(3)\n", "\n", "# create an iterable from the object\n", "i = iter(numbers)\n", "\n", "# Using next to get to the next iterator element\n", "print(next(i)) # prints 1\n", "'''\n", "print(next(i)) # prints 2\n", "print(next(i)) # prints 4\n", "print(next(i)) # prints 8\n", "print(next(i)) # raises StopIteration exception\n", "'''\n", "from itertools import count\n", "\n", "# create an infinite iterator that starts at 1 and increments by 1 each time\n", "infinite_iterator = count(1)\n", "\n", "# print the first 5 elements of the infinite iterator\n", "for i in range(5):\n", " print(next(infinite_iterator))\n", "\n", "\n", "class SequenceIterator:\n", " def __init__(self, sequence):\n", " self._sequence = sequence\n", " self._index = 0\n", "\n", " def __iter__(self):\n", " return self\n", "\n", " def __next__(self):\n", " if self._index < len(self._sequence):\n", " item = self._sequence[self._index]\n", " self._index += 1\n", " return item\n", " else:\n", " raise StopIteration\n", "\n", "for item in SequenceIterator([1, 2, 3, 4]):\n", " print(item)\n", "\n", "\n" ] }, { "cell_type": "markdown", "source": [ "# **Create an Iterator**\n", "To create an object/class as an iterator you have to implement the methods __iter__() and __next__() to your object.\n", "\n", "As you will learned in the Python Classes/Objects chapter, all classes have a function called __init__(), which allows you to do some initializing when the object is being created.\n", "\n", "The __iter__() method acts similar, you can do operations (initializing etc.), but must always return the iterator object itself.\n", "\n", "The __next__() method also allows you to do operations, and must return the next item in the sequence." ], "metadata": { "id": "stB9qiFesROM" } }, { "cell_type": "code", "source": [ "class SquareIterator:\n", " def __init__(self, sequence):\n", " self._sequence = sequence\n", " self._index = 0\n", "\n", " def __iter__(self):\n", " return self\n", "\n", " def __next__(self):\n", " if self._index < len(self._sequence):\n", " square = self._sequence[self._index] ** 2\n", " self._index += 1\n", " return square\n", " else:\n", " raise StopIteration\n", "\n", "class FibonacciIterator:\n", " def __init__(self, stop=10):\n", " self._stop = stop\n", " self._index = 0\n", " self._current = 0\n", " self._next = 1\n", "\n", " def __iter__(self):\n", " return self\n", "\n", " def __next__(self):\n", " if self._index < self._stop:\n", " self._index += 1\n", " fib_number = self._current\n", " self._current, self._next = (\n", " self._next,\n", " self._current + self._next,\n", " )\n", " return fib_number\n", " else:\n", " raise StopIteration\n", "\n", "\n", "class FibonacciInfIterator:\n", " def __init__(self):\n", " self._index = 0\n", " self._current = 0\n", " self._next = 1\n", "\n", " def __iter__(self):\n", " return self\n", "\n", " def __next__(self):\n", " self._index += 1\n", " self._current, self._next = (self._next, self._current + self._next)\n", " return self._current\n", "\n", "\n", "from collections.abc import Iterator\n", "\n", "class SequenceIterator(Iterator):\n", " def __init__(self, sequence):\n", " self._sequence = sequence\n", " self._index = 0\n", "\n", " def __next__(self):\n", " if self._index < len(self._sequence):\n", " item = self._sequence[self._index]\n", " self._index += 1\n", " return item\n", " else:\n", " raise StopIteration\n", "\n", "\n", "def to_square(numbers):\n", " return (number**2 for number in numbers)\n", "\n", "def to_cube(numbers):\n", " return (number**3 for number in numbers)\n", "\n", "def to_even(numbers):\n", " return (number for number in numbers if number % 2 == 0)\n", "\n", "def to_odd(numbers):\n", " return (number for number in numbers if number % 2 != 0)\n", "\n", "def to_string(numbers):\n", " return (str(number) for number in numbers)\n", "\n", "class ReusableRange:\n", " def __init__(self, start=0, stop=None, step=1):\n", " if stop is None:\n", " stop, start = start, 0\n", " self._range = range(start, stop, step)\n", " self._iter = iter(self._range)\n", "\n", " def __iter__(self):\n", " return self\n", "\n", " def __next__(self):\n", " try:\n", " return next(self._iter)\n", " except StopIteration:\n", " self._iter = iter(self._range)\n", " raise\n", "\n", "# 1. Start with an iterable (a list)\n", "my_list = ['apple', 'banana', 'cherry']\n", "\n", "# 2. Get an iterator object from the iterable\n", "my_iterator = iter(my_list)\n", "\n", "# 3. Get the current (next) item from the iterator\n", "current_item = next(my_iterator)\n", "print(current_item)\n", "# Outputs: apple\n", "\n", "# 4. Get the next item again\n", "current_item = next(my_iterator)\n", "print(current_item)\n", "# Outputs: banana\n", "\n", "my_list = [10, 20, 30]\n", "iterator = iter(my_list)\n", "\n", "print(next(iterator)) # Output: 10\n", "print(next(iterator)) # Output: 20\n", "print(next(iterator)) # Output: 30\n", "\n", "my_tuple = (1, 2, 3, 4)\n", "for item in iter(my_tuple):\n", " print(item)\n", "\n", "\n", "class Counter:\n", " def __init__(self, start, end):\n", " self.current = start\n", " self.end = end\n", "\n", " def __iter__(self):\n", " return self\n", "\n", " def __next__(self):\n", " if self.current > self.end:\n", " raise StopIteration\n", " self.current += 1\n", " return self.current - 1\n", "\n", "counter = Counter(1, 5)\n", "for num in counter:\n", " print(num) # Outputs: 1, 2, 3, 4, 5\n", "'''\n", "with open(\"data.txt\", \"r\") as file:\n", " for line in iter(file.readline, \"\"):\n", " print(line.strip())\n", "'''\n", "my_dict = {\"a\": 1, \"b\": 2, \"c\": 3}\n", "dict_iterator = iter(my_dict)\n", "\n", "print(next(dict_iterator)) # Output: a\n", "print(next(dict_iterator)) # Output: b\n", "print(next(dict_iterator)) # Output: c\n", "\n", "for value in my_dict.values():\n", " print(value) # Output: 1, 2, 3\n", "\n", "for key, value in my_dict.items():\n", " print(f\"{key}: {value}\") # Output: a: 1, b: 2, c: 3\n", "\n", "class EvenNumbers:\n", " def __init__(self, max_number):\n", " self.number = 0\n", " self.max = max_number\n", "\n", " def __iter__(self):\n", " return self\n", "\n", " def __next__(self):\n", " if self.number > self.max:\n", " raise StopIteration\n", " self.number += 2\n", " return self.number - 2\n", "\n", "even_iterator = EvenNumbers(10)\n", "for num in even_iterator:\n", " print(num) # Output: 0, 2, 4, 6, 8, 10\n", "\n", "fruits = [\"apple\", \"banana\", \"cherry\"]\n", "for index, fruit in enumerate(fruits):\n", " print(f\"{index}: {fruit}\")\n", "# Output:\n", "# 0: apple\n", "# 1: banana\n", "# 2: cherry\n", "\n", "def count_up_to(maximum):\n", " num = 1\n", " while num <= maximum:\n", " yield num\n", " num += 1\n", "\n", "counter = count_up_to(5)\n", "print(next(counter)) # Output: 1\n", "print(next(counter)) # Output: 2\n", "\n", "names = [\"Alice\", \"Bob\", \"Charlie\"]\n", "scores = [85, 90, 78]\n", "\n", "for name, score in zip(names, scores):\n", " print(f\"{name}: {score}\")" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "QeVl-q2isRV8", "outputId": "dbd35805-72fd-451a-8f5a-8edcabb48dd1" }, "execution_count": 4, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "apple\n", "banana\n", "10\n", "20\n", "30\n", "1\n", "2\n", "3\n", "4\n", "1\n", "2\n", "3\n", "4\n", "5\n", "a\n", "b\n", "c\n", "1\n", "2\n", "3\n", "a: 1\n", "b: 2\n", "c: 3\n", "0\n", "2\n", "4\n", "6\n", "8\n", "10\n", "0: apple\n", "1: banana\n", "2: cherry\n", "1\n", "2\n", "Alice: 85\n", "Bob: 90\n", "Charlie: 78\n" ] } ] }, { "cell_type": "markdown", "source": [ "# **StopIteration**\n", "The example above would continue forever if you had enough next() statements, or if it was used in a for loop.\n", "\n", "To prevent the iteration from going on forever, we can use the StopIteration statement.\n", "\n", "In the __next__() method, we can add a terminating condition to raise an error if the iteration is done a specified number of times:" ], "metadata": { "id": "u0RMkCYisReH" } }, { "cell_type": "code", "source": [ "names = [\"Alice\", \"Bob\", \"Charlie\"]\n", "scores = [85, 90, 78]\n", "\n", "for name, score in zip(names, scores):\n", " print(f\"{name}: {score}\")\n", "\n", "import os\n", "\n", "for entry in os.scandir(\".\"):\n", " print(entry.name)\n", "\n", "from pathlib import Path\n", "\n", "for file in Path(\".\").iterdir():\n", " print(file)\n", "\n", "\n", "squares = (lambda x: x ** 2 for x in range(5))\n", "for square in squares:\n", " print(square)\n", "\n", "# define an iterable such as a list\n", "list1=[1,2,3,4,5,6,7,8,9,0]\n", "\n", "# get an iterator using iter()\n", "iter1=iter(list1)\n", "# infinite loop\n", "while True:\n", " try:\n", " # get the next item\n", " print(next(iter1))\n", " # do something with element\n", " except StopIteration:\n", " # if StopIteration is raised, break from loop\n", " break\n", "\n", "list1=[1,2,3,4,5,6,7,8,9,0]\n", "for i in list1:\n", " print(i)\n", "\n", "\n", "list2=[1,2,\"hello\",[9,8,7],(11,12),{'one': 'husaain'}]\n", "for i in list2:\n", " print(i)\n", "\n", "string=\"Hello World \"\n", "for i in string:\n", " print(i)\n", "\n", "\n", "class Evenit:\n", "\n", " def __init__(self, max=0):\n", " self.max = max\n", "\n", " def __iter__(self):\n", " self.n = 0\n", " return self\n", "\n", " def __next__(self):\n", " if self.n <= self.max:\n", " if self.n % 2 ==0:\n", " result=self.n\n", " self.n += 1\n", " return result\n", " else:\n", " self.n += 1\n", " return 1\n", " else:\n", " raise StopIteration\n", "\n", "\n", "# create an object\n", "numbers = Evenit(10)\n", "\n", "for i in numbers:\n", "\tprint(i)\n", "\n", "list_instance = [1, 2, 3, 4]\n", "print(iter(list_instance))\n", "\n", "\"\"\"\n", "\n", "\"\"\"\n", "\n", "# instantiate a list object\n", "list_instance = [1, 2, 3, 4]\n", "\n", "# convert the list to an iterator\n", "iterator = iter(list_instance)\n", "\n", "# return items one at a time\n", "print(next(iterator))\n", "print(next(iterator))\n", "print(next(iterator))\n", "print(next(iterator))\n", "\"\"\"\n", "1\n", "2\n", "3\n", "4\n", "\"\"\"\n", "\n", "# instantiate a list object\n", "list_instance = [1, 2, 3, 4]\n", "\n", "# loop through the list\n", "for iterator in list_instance:\n", " print(iterator)\n", "\"\"\"\n", "1\n", "2\n", "3\n", "4\n", "\"\"\"\n", "\n", "list_instance = [1, 2, 3, 4]\n", "iterator_a = iter(list_instance)\n", "iterator_b = iter(list_instance)\n", "print(f\"A: {next(iterator_a)}\")\n", "print(f\"A: {next(iterator_a)}\")\n", "print(f\"A: {next(iterator_a)}\")\n", "print(f\"A: {next(iterator_a)}\")\n", "print(f\"B: {next(iterator_b)}\")\n", "\"\"\"\n", "A: 1\n", "A: 2\n", "A: 3\n", "A: 4\n", "B: 1\n", "\"\"\"\n", "\n", "# instantiate iterable\n", "list_instance = [1, 2, 3, 4]\n", "\n", "# produce an iterator from an iterable\n", "iterator = iter(list_instance)\n", "print(list(iterator))\n", "\"\"\"\n", "[1, 2, 3, 4]\n", "\"\"\"\n", "\n", "def factors(n):\n", " factor_list = []\n", " for val in range(1, n+1):\n", " if n % val == 0:\n", " factor_list.append(val)\n", " return factor_list\n", "\n", "print(factors(20))\n", "\"\"\"\n", "[1, 2, 4, 5, 10, 20]\n", "\"\"\"\n", "\n", "def factors(n):\n", " for val in range(1, n+1):\n", " if n % val == 0:\n", " yield val\n", "print(factors(20))\n", "\n", "\"\"\"\n", "\n", "\"\"\"\n", "\n", "def factors(n):\n", " for val in range(1, n+1):\n", " if n % val == 0:\n", " yield val\n", "\n", "factors_of_20 = factors(20)\n", "print(next(factors_of_20))\n", "\n", "\"\"\"\n", "1\n", "\"\"\"\n", "\n", "print((val for val in range(1, 20+1) if n % val == 0))\n", "\"\"\"\n", " at 0x7fd940c31e50>\n", "\"\"\"\n", "\n", "def yield_multiple_statments():\n", " yield \"This is the first statment\"\n", " yield \"This is the second statement\"\n", " yield \"This is the third statement\"\n", " yield \"This is the last statement. Don't call next again!\"\n", "example = yield_multiple_statments()\n", "print(next(example))\n", "\n", "\"\"\"\n", "This is the first statment\n", "This is the second statement\n", "This is the third statement\n", "This is the last statement. Don't call next again or else!\n", "--------------------------------------------------------------------\n", "StopIteration Traceback (most recent call last)\n", " in ()\n", " 11 print(next(example))\n", " 12 print(next(example))\n", "---> 13 print(next(example))\n", "StopIteration:\n", "\"\"\"\n" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "id": "9_fh8-AvsRm1", "outputId": "5cec5817-f701-4af8-ae0e-5b9fdfe985a2" }, "execution_count": 6, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Alice: 85\n", "Bob: 90\n", "Charlie: 78\n", ".config\n", "sample_data\n", ".config\n", "sample_data\n", ". at 0x7bfd4773cae0>\n", ". at 0x7bfd5c0839c0>\n", ". at 0x7bfd4773cae0>\n", ". at 0x7bfd5c0839c0>\n", ". at 0x7bfd4773cae0>\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "0\n", "1\n", "2\n", "hello\n", "[9, 8, 7]\n", "(11, 12)\n", "{'one': 'husaain'}\n", "H\n", "e\n", "l\n", "l\n", "o\n", " \n", "W\n", "o\n", "r\n", "l\n", "d\n", " \n", "0\n", "1\n", "2\n", "1\n", "4\n", "1\n", "6\n", "1\n", "8\n", "1\n", "10\n", "\n", "1\n", "2\n", "3\n", "4\n", "1\n", "2\n", "3\n", "4\n", "A: 1\n", "A: 2\n", "A: 3\n", "A: 4\n", "B: 1\n", "[1, 2, 3, 4]\n", "[1, 2, 4, 5, 10, 20]\n", "\n", "1\n", " at 0x7bfd4760ca00>\n", "This is the first statment\n" ] }, { "output_type": "execute_result", "data": { "text/plain": [ "\"\\nThis is the first statment\\nThis is the second statement\\nThis is the third statement\\nThis is the last statement. Don't call next again or else!\\n--------------------------------------------------------------------\\nStopIteration Traceback (most recent call last)\\n in ()\\n 11 print(next(example))\\n 12 print(next(example))\\n---> 13 print(next(example))\\nStopIteration:\\n\"" ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" } }, "metadata": {}, "execution_count": 6 } ] }, { "cell_type": "markdown", "source": [ "# **Iterators in Python**\n", "Last Updated : 03 Sep, 2025\n", "An iterator in Python is an object used to traverse through all the elements of a collection (like lists, tuples or dictionaries) one element at a time. It follows the iterator protocol, which involves two key methods:\n", "\n", "__iter__(): Returns the iterator object itself.\n", "__next__(): Returns the next value from the sequence. Raises StopIteration when the sequence ends.\n", "Why do we need iterators?\n", "Here are some key benefits:\n", "\n", "Lazy Evaluation: Processes items only when needed, saving memory.\n", "Generator Integration: Pairs well with generators and functional tools.\n", "Stateful Traversal: Keeps track of where it left off.\n", "Uniform Looping: Same for loop works for lists, strings and more.\n", "Composable Logic: Easily build complex pipelines using tools like itertools.\n", "Built-in Iterator Example\n", "Let’s start with a simple example using a string. We will convert it into an iterator and fetch characters one by one:" ], "metadata": { "id": "hLB3aw3nsRvd" } } ] }