Table of Contents
What is reversed?
The reversed class is used to create a reverse iterator from an object .
This object , must either implement the __getitem__
and the __len__
special methods . In this case reverse will create an iterator from this object . Or the object must implement the __reversed__
method , and the __reversed__
method must return an iterator .
reversed
can be used with python builtin types , that implements the __reversed__
method . It can also be used with python built in types , that implement the sequence protocol , like the list , which implements the : __getitem__
and __len__
methods .
reversed
can also be used with custom created types , that implement the __getitem__
and __len__
methods , or that implement the __reversed__
method , which must return an iterator .
Using reverse with built-in python types
# #### example one : reversed with built-in types #### >>> _printList = ['_oo_', '|__|', '(^|^)'] >>> print(list(reversed(_printList))) # list implements the sequence protocol # get a reverse iterator from _printList using # reversed # create a list # print the reversed list ['(^|^)', '|__|', '_oo_'] >>> work = "eciohc fo rewop ehT" >>> print(''.join(reversed(work))) # string implements the sequence protocol # get a reverse iterator from work string # using reverse . # join the iterator using the empty string # the result is The power of choice >>> list(filter(lambda word: set(word) & {'a', 'e', 'i', 'o', 'u'}, reversed( ["flavors", "ft", "kg", "blink", "cash", "food", "eggs"]))) # reverse the list # filter it using a lambda function # return true if the word contain a vowel # create a list from the resulting iterator # result ['eggs', 'food', 'cash', 'blink', 'flavors'] >>> temperatures = [0, 12, 23, 34] for temperature in reversed(temperatures): print(temperature, end=';') # reverse the temperature in a list and print them # output : 34;23;12;0; # a useful example of reverse is to test for the # associativity of an operation # let us say we want to test if the addition of two # strings is associative >>> data = ["a", "b"] # data >>> sum_left_to_right = '' >>> sum_right_to_left = '' # sums from left to right and from right to left = '' for _data in data: sum_left_to_right += _data # sum the data from left to right for _data in reversed(data): sum_right_to_left += _data # sum the data from right to left if sum_left_to_right == sum_right_to_left: print("The sum of strings is associative") else: print("The sum of strings is not associative") # output The sum of strings is not associative >>> _dict = {'g':'e' , 1:2} >>> reversed(_dict) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'dict' object is not reversible # dictionaries do not implement the # __reverse__ method or the sequence # protocol , trying to reverse a # dictionary will raise a TypeError
Using reversed with custom types that implement __getitem__ and __len__
# example two : reversed with custom types that implements _getitem__ and __len__ class Bar: ''' Bar class implements __getitem__ , __len__ Show how to use reverse function with a type that implements __getitem__ __len__ default bar is iterated from start to stop -> the bar is filled reverse iterate the bar from stop to start -> the bar is emptied ''' def __init__(self, start=0, stop=15): ''' bar [|||||||||||||||] start:0 stop:15 ''' self.start = start self.stop = stop def __getitem__(self, barIndex): if barIndex < self.start or barIndex >= self.stop: raise IndexError # barIndex must be between [start and stop) return barIndex - self.start def __len__(self): return self.stop - self.start >>> bar = Bar() >>> list(bar) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> list(reversed(bar)) [14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Using reversed with custom types that implements __reversed__ , __reversed__ returns a class that implements __iter__ and __next__
class Problems: ''' Contains problems that we want to check. We want to be able to check the problems from the first that was inserted to the last that was inserted. We also want to be able to check the problems from the last that was inserted to the first that was inserted. We can implement the __reversed__ method that must return an iterator. ''' def __init__(self): self.problems = ['undefined', 'check', 'unexpected', 'indent'] def __iter__(self): ''' returns an iterator , that iterates through the problems from first to last . ''' return iter(self.problems) def __reversed__(self): '''__reversed__ creates an instance of the ProblemsReversed class which implements the __iter__ and __next__ methods ''' class ProblemsReversed: def __init__(self, problems): self.problems = problems self.counter = len(self.problems) def __iter__(self): ''' ProblemsReverseIterator is iterable. it returns an iterator , it implements __next__ ,as such it can return itself ''' return self def __next__(self): ''' iterate through the problems from [length-1 , 0 ] ''' if self.counter > 0: self.counter -= 1 return self.problems[self.counter] raise StopIteration return ProblemsReversed(self.problems) >>> problems = Problems() >>> list(problems) # list the problems from first to last ['undefined', 'check', 'unexpected', 'indent'] >>> list(reversed(problems)) # list the problems from last to first ['indent', 'unexpected', 'check', 'undefined']
Using reversed with custom types that implements __reversed__ , __reversed__ returns a generator
class Print: ''' iterate through a string , from start till end , and from end till start ''' def __init__(self, string=''' 0 : 0 0 | '''): self.string = string def __iter__(self): ''' returns an iterator , that iterates through a string from start till end ''' return iter(self.string) def __reversed__(self): ''' returns a generator object , that iterates through a string , from end to start ''' string = self.string return ( string[i] for i in range(len(string) -1 , -1 , -1) ) # create a range from [len(string)-1 , 0] # For indexes in the range , access the characters # in string , from end till start # return the generator object >>> mPrint = Print() >>> print(''.join(iter(mPrint))) # get an iterator from mPrint , # join it using the empty string # and print the result # output 0 : 0 0 | >>> print(''.join(reversed(mPrint))) # get a reverse iterator from mPrint , # join it using the empty string # and print the result # output | 0 0 : 0