0

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)?

2 Answers 2

2

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 and in 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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.