Python Defensive Iteration
This is the item 12 explained in the "Effective Python", by Brett Slatkin. Generators are the best save of out of memory problem. Here the problem,
class StringToList(object):
def __init__(self, text):
self.text = text
def __iter__(self):
for x in self.text:
yield x
words = StringToList('Hello')
# case 1
it = iter(words)
it2 =iter(it)
print(it, it2) #(<generator object __iter__ at 0x10816d7d0>, <generator object __iter__ at 0x10816d7d0>)
next(it) # 'H'
next(it2) # 'e'
The problem is it
and it2
pointing to the same instance and iteration is not as expected ('it2' give a next element as 'e' instead 'H'). To overcome this problem, author has suggested the following solution which is applicable to set and dict as well. In the case 1, same container is used. But in the case 2, different containsers.
# case 2
it = iter(words)
it2 =iter(words)
print(it, it2) # (<generator object __iter__ at 0x10816d550>, <generator object __iter__ at 0x10816d320>)
next(it) # 'H'
next(it2) # 'H'
In the above code, diffrent instaces because two diffrent containers. To defence from the case 1, need to use the following defence and avoid:
if it is it2:
raise TypeError('Same container error')
else:
print(next(it)) # 'H'
print(next(it2)) # 'H'
That will promote the case 2 style of programming.
Comments
Post a Comment
commented your blog