Reputation: 91
I have read some posts on stackoverflow about how to check an object is an iterator in Python but it seems that they did not solve my question. I have this example from the book Effective Python
def normalize_defensive(numbers):
if iter(numbers) is iter(numbers): # An iterator — bad!
raise TypeError(‘Must supply a container’)
total = sum(numbers)
result = []
for value in numbers:
percent = 100 * value / total
result.append(percent)
return result
To use:
visits = [15, 35, 80]
normalize_defensive(visits) # No error
visits = ReadVisits(path) # ReadVisits is a class with an __iter__ method.
normalize_defensive(visits) # No error
it = iter(visits)
normalize_defensive(it)
>>>
TypeError: Must supply a container
So my question is in this line:
if iter(numbers) is iter(numbers): # An iterator — bad!
Why this line check if the variable numbers is an iterator? When visits = [15, 35, 80], should it be true that iter(numbers) is iter(numbers)
?
Upvotes: 0
Views: 198
Reputation: 1121914
When you call an iterable, calling iter()
on such an object will always produce a new iterator object. But calling iter()
on an iterator will always return the same object; it is a requirement of the iterator protocol that they do.
From the iterator.__iter__()
documentation:
Return the iterator object itself. This is required to allow both containers and iterators to be used with the
for
andin
statements.
Because iter(iterable)
always returns itself, the test iter(obj) is iter(obj)
will be true; the same object is returned in both cases.
Upvotes: 2
Reputation: 78556
To help you understand Martijn's explanation, take a look at the following:
>>> numbers = [15, 35, 80]
>>> it = iter(numbers)
>>> it2 = iter(numbers)
>>> it3 = iter(it)
>>> id(it1)
51123792
>>> id(it2)
51056464 # id of it2 is different from it1
>>> id(it3)
51123792 # iterator of iterator it3 has the same id as iterator it1
So if numbers
was an iterator
, calling iter
on numbers
will always return objects that are internally identical: iter(numbers) is iter(numbers)
will be True
.
Upvotes: 0