lambda itself does not iterate over anything. As you thought, it simply defines an anonymous function - in addition to the syntax rule just for the possibility of having an expression, lambda does nothing more than a similar function created with def . The code inside the lambda can repeat something, but only in the same way as any other function (if they are expressions and therefore valid inside lambda ).
In the example that you mention with sorted , the key function is called for each element of the sorted list, but it itself sorted does it and does an iteration. When you provide a key function, sorted does something like this:
def sorted(seq, key): decorated = [(key(elem), i) for i, elem in enumerate(seq)]
As you can see, sorted here, not lambda . Indeed, there is no reason why the key should be lambda - any function (or any called) will do before sorted .
At the lowest level, there is only one way to iterate through a dict (or indeed any other iterable) in Python that needs to use the iterator protocol. This is what the for loop runs behind the scenes, and you can also use the while statement as follows:
it = iter(my_iterable) while True: try: val = next(it) except StopIteration: # Run else clause of for loop break else: # Run for loop body
The comments in this are not strictly part of the iterator protocol, they are part of the for loop (but having at least the body of the loop, this is basically the iteration point in the first place).
Other functions and syntax that consume iterations (such as list, set, and dictations, generator expressions, or inline expressions such as sum , sorted or max ) use this protocol either:
- Using the Python
for loop, - Running something like the above
while (especially for modules written in C), - Delegating to another function or piece of syntax that uses one of these
A class can be made so that its instances become iterable in one of two ways:
- Provide an iterator protocol directly. You need a method called
__iter__ (called by iter ) that returns an iterator. This iterator has a method called __next__ (just next in Python 2), which is called next and returns the value at the current location of the iterator and advances it (or raises StopIteration if it is already at the end); or - Implement a portion of the sequence protocol (which means that you behave like a list or tuple). For forward iteration, it is sufficient to define
__getitem__ so that my_sequence[0] , my_sequence[1] , up to my_sequence[n-1] (where n is the number of elements in the sequence), and higher indices increase the error. Usually you also want to define __len__ , which is used when you do len(my_sequence) .