{
"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": [
"
"
]
},
{
"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"
}
}
]
}