Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test equivalence of ranges

One of my unittests checks to see if a range is set up correctly after reading a log file, and I'd like to just test var == range(0,10). However, range(0,1) == range(0,1) evaluates to False in Python 3.

Is there a straightforward way to test the equivalence of ranges in Python 3?

like image 917
oneporter Avatar asked Oct 12 '11 13:10

oneporter


3 Answers

In Python3, range returns an iterable of type range. Two ranges are equal if and only if they are identical (i.e. share the same id.) To test equality of its contents, convert the range to a list:

list(range(0,1)) == list(range(0,1))

This works fine for short ranges. For very long ranges, Charles G Waldman's solution is better.

like image 108
unutbu Avatar answered Sep 30 '22 18:09

unutbu


The first proposed solution - use "list" to turn the ranges into lists - is ineffecient, since it will first turn the range objects into lists (potentially consuming a lot of memory, if the ranges are large), then compare each element. Consider e.g. a = range(1000000), the "range" object itself is tiny but if you coerce it to a list it becomes huge. Then you have to compare one million elements.

Answer (2) is even less efficient, since the assertItemsEqual is not only going to instantiate the lists, it is going to sort them as well, before doing the elementwise comparison.

Instead, since you know the objects are ranges, they are equal when their strides, start and end values are equal. E.g.

ranges_equal = len(a)==len(b) and (len(a)==0 or a[0]==b[0] and a[-1]==b[-1])

like image 45
Charles G Waldman Avatar answered Sep 30 '22 17:09

Charles G Waldman


Try assertItemsEqual, (in the docs):

class MyTestCase(unittest.TestCase):
    def test_mytest(self):
        a = (0,1,2,3,4)
        self.assertItemsEqual(a, range(0,4))
like image 33
Constantinius Avatar answered Sep 30 '22 18:09

Constantinius