Junior — Senior
Features of filter and one-time iterators
livecode
Task condition
Analyze why this program outputs exactly this result and what features of filter and iterators lead to this.
seq = [1, 2, 3, 4, 5]
# Get an iterator of odd numbers from seq
odd_iter = filter(lambda x: x % 2, seq)
if any(odd_iter):
print("Has odds:")
for odd in odd_iter:
print(odd)
print(any(odd_iter))
Program output:
Has odds:
3
5
False
What happens:
filterreturns an iterator, not a list. Its elements are computed "on the fly" and can only be retrieved once.- In the condition
if any(odd_iter):theanyfunction iterates over the iterator until it finds a true (True) value. The first two odd numbers —1and3— are checked, and once3(a true value) is found, the iteration stops. The iterator has already been "advanced" past the element3to5. - After executing
any, the iterator is in a "spent" state: the elements that have already been passed are no longer accessible. Therefore, in the subsequentfor odd in odd_iter:only the remaining element —5— is left, which is printed. - The last call
any(odd_iter)again tries to iterate over the remaining elements. Since after printing5there are no more elements in the iterator,anyimmediately returnsFalse.
In summary, filter creates a one-time iterator, and any functions that consume it (any, list, for loop, etc.) "exhaust" it, making subsequent attempts to retrieve data empty.