Introduction To “Iterable” and “Iterator”
4 min readDec 27, 2022
Why “Iterables” and “Iterators” are Required?
- “Comprehensions”, and, “for” Loops are the “Most Frequently Used Language Features” for “Performing” the “Iteration”. That is, “Taking Elements One by One” from a “Source”, and, “Doing Something” with “Each Element” in turn.
- However, “both” the “Comprehensions”, and, “for” Loops “Iterate Over” the “Whole Sequence” by default.
- When, “More Fine-Grained Control” is “Needed”, there are “Two Approaches” -
- 1. Iterable Objects — The “Iterable Protocol” “Allows” to “Pass” an “Iterable Object”, usually a “Collection”, or, “Stream of Objects”, such as a “List” to the Built-In Function “iter ()” to “Get” an “Iterator” for the “Iterable Object”.
- 2. Iterator Objects — The “Iterable Objects”, in turn, “Support” the “Iterator Protocol”, which “Requires” to “Pass” the “Iterator Object” to the Built-In Function “next ()” to “Fetch” the “Next Value” from the “Underlying Collection”.
“Each Call” to the Built-In Function “next ()” “Moves” the “Iterator” through the “Underlying Collection”.
# Create a "List" of "Strings" Containing "Names"
2
listOfNames = ["Oindrila", "Soumyajyoti", "Oishi", "Souvik", "Anamika", "Swaralip", "Soumyajit", "Sagarneel", "Abhirup", "Madhura"]
iterableListOfNames = iter(listOfNames)
print(next(iterableListOfNames))
print(next(iterableListOfNames))
print(next(iterableListOfNames))
print(next(iterableListOfNames))
print(next(iterableListOfNames))
print(next(iterableListOfNames))
print(next(iterableListOfNames))
print(next(iterableListOfNames))
print(next(iterableListOfNames))
print(next(iterableListOfNames))
When the “Iterator” Reaches the “End”
- When the “Iterator” “Reaches” the “End” of the “Underlying Collection”, “Python” “Raises” an “Exception”, specifically of the Type “StopIteration”.
print(next(iterableListOfNames))
Clear Example of “Iterable” and “Iterator”
- With “for” Loops, and, “Comprehensions” at the “User’s Fingertips”, the “Utility” of the “Lower Level Iteration Protocols” “May Not” be “Obvious”.
- To “Demonstrate” “More Concrete Use”, let’s “Create” the following “Utility Function”, which, when an “Iterable Object” is “Passed”, “Returns” the “First Item” in the “Underlying Collection”, or, “If” the “Underlying Collection” is “Empty”, the “Utility Function” “Raises” a “ValueError” Exception -
- First, “Call” the Built-In Function “iter ()” on the “Input Iterable Object” to “Produce” an “Iterator”.
- Second, the Built-In Function “next ()” is “Called” on the “Iterator” “Inside” a “try” Block that “Returns” the “Result”.
If the “Input Iterable” is “Empty”, the Built-In Function “next ()” has “No Value” to “Return”, and, it instead “Raises” a “StopIteration” Exception.
The “StopIteration” Exception is “Caught” in the “except” Block, and, a “ValueError” Exception is “Raised”. - This “Utility Function” “Works as Expected” on “Any Iterable Object”.
def returnFirstElement (iterableObj):
iteratorObj = iter(iterableObj)
try:
return next(iteratorObj)
except StopIteration:
raise ValueError("Iterable Object is Empty")
Clear Example of “Iterable” and “Iterator” with “String”
# Create a "String"
name = 'Oindrila Chakraborty'
print(returnFirstElement(name))
# Create an "Empty String"
emptyString = ''
print(returnFirstElement(emptyString))
Clear Example of “Iterable” and “Iterator” with “List”
# Create a "List" of "Integers"
listOfIntNumbers = [25, 19, 15, 20, 1, 7, 0, 21, 29, 35, 55]
print(returnFirstElement(listOfIntNumbers))
# Create an "Empty List"
emptyList = []
print(returnFirstElement(emptyList))
Clear Example of “Iterable” and “Iterator” with “Tuple”
# Create a "Tuple" of "Integers"
tupleOfIntNumbers = (25, 19, 15, 20, 1, 7, 0, 21, 29, 35, 55)
print(returnFirstElement(tupleOfIntNumbers))
# Create an "Empty Tuple"
emptyTuple = ()
print(returnFirstElement(emptyTuple))
Clear Example of “Iterable” and “Iterator” with “Set”
# Create a "Set" of "Integers"
setOfIntNumbers = {25, 19, 15, 20, 1, 7, 0, 21, 29, 35, 55}
print(returnFirstElement(setOfIntNumbers))
# Create an "Empty Set"
emptySet = set()
print(returnFirstElement(emptySet))
Clear Example of “Iterable” and “Iterator” with “Dictionary”
# Create a "Dictionary" Having Name" as the "Key", and, the Corresponding "Person's Age" as the "Value"
dictPerson = {
"Oindrila": 34,
"Soumyajyoti": 35,
"Premanshu": 66,
"Rama": 61,
"Kasturi": 29
}
print(returnFirstElement(dictPerson))
# Create an "Empty Dictionary"
emptyDictionary = {}
print(returnFirstElement(emptyDictionary))
- It is worth noting that the “Higher-Level Iteration Constructions”, such as “for” Loops, and, “Comprehensions” are “Built Directly” upon the “Lower-Level Iteration Protocol”.