<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Python Iterators
As common sense suggest, Iterators are object which can be iterated upon such as list, dictionary, string etc. In Python they are literally everywhere. 
They are objects which when iterated retuns one element at a time. We have already seen most of the inbuilt iterators, such as list, tuple, dictionary, string, etc. In this chapter we are going to create our own custom iterators.
There are few ways in which we can create a custom iterators.
Class Methods
In order to create a python iterator, our custom class must implement two special methods, __iter__() and __next__(), which collectively are called the iterator protocol.
Step1:  iter()
The iter() method returns an iterator for the given object.
Syntax
Step2:  lets try another example, this time lets take a string
<ASSISTANT_TASK:>
Python Code:
class MyIter(object):
    def __init__(self, lst):
        self.lst = lst
        self.i = 0
    
    def __iter__(self):
        self.i = 0
        return self
    
    def __next__(self):
        if self.i < len(self.lst):
            nxt = self.lst[self.i]
            self.i +=1
            return nxt
        else:
            raise StopIteration
m = MyIter([1, 2, 3, 4, 5, 6])
for a in m:
    print(a)
Explanation: Python Iterators
As common sense suggest, Iterators are object which can be iterated upon such as list, dictionary, string etc. In Python they are literally everywhere. 
They are objects which when iterated retuns one element at a time. We have already seen most of the inbuilt iterators, such as list, tuple, dictionary, string, etc. In this chapter we are going to create our own custom iterators.
There are few ways in which we can create a custom iterators.
Class Methods
In order to create a python iterator, our custom class must implement two special methods, __iter__() and __next__(), which collectively are called the iterator protocol.
End of explanation
class MyDummy(object):
    def __init__(self):
        self.lst = [1, 2, 3, 4, 5, 6]
        self.i = 0
        
    def __call__(self):
        ret = self.lst[self.i]
        self.i += 1
        return ret
d = MyDummy()
for a in iter(d, 3):
    print(a, end=" ")
m = MyIter([1, 2, 3, 4, 5, 6])
for a in iter(m):
    print(a, end=" ")
Explanation: iter()
The iter() method returns an iterator for the given object.
Syntax:
python
iter(object[, sentinel])
Where object is an object based on which the iterator needs to be constructed. The behavior of iterator is dependent on the value of sentinel, if sentinel is not provided then object should be an interator and the construct will behave as such, where as if sentinel is provided then object should be callable, and value returned will be treated as next call. Iteration ends when the value retuned equals to value in sentinel
End of explanation
st = "Welcome to the city of lakes"
for a in iter(st):
    print(a, end=" ")
Explanation: lets try another example, this time lets take a string
End of explanation
<END_TASK>