简体   繁体   English

如何测试范围的等价性

[英]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) . 我的一个单元测试检查读取日志文件后是否正确设置了一个范围,我想测试var == range(0,10) However, range(0,1) == range(0,1) evaluates to False in Python 3. 但是, range(0,1) == range(0,1)在Python 3中的计算结果为False

Is there a straightforward way to test the equivalence of ranges in Python 3? 有没有一种直接的方法来测试Python 3中的范围等价?

In Python3, range returns an iterable of type range . 在Python3中, range返回类型range的可迭代。 Two range s are equal if and only if they are identical (ie share the same id .) To test equality of its contents, convert the range to a list : 当且仅当两个range相同时(即共享相同的id ),两个range是相等的。为了测试其内容的相等性,将range转换为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. 对于很长的范围, Charles G Waldman的解决方案更好。

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. 第一个提出的解决方案 - 使用“list”将范围转换为列表 - 是无效的,因为它首先将范围对象转换为列表(如果范围很大,可能会占用大量内存),然后比较每个元素。 Consider eg a = range(1000000), the "range" object itself is tiny but if you coerce it to a list it becomes huge. 考虑例如a = range(1000000),“range”对象本身很小但是如果你强制它到列表它会变得很大。 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. 答案(2)效率更低,因为assertItemsEqual不仅要实例化列表,而且还要在进行元素比较之前对它们进行排序。

Instead, since you know the objects are ranges, they are equal when their strides, start and end values are equal. 相反,由于您知道对象是范围,因此当它们的步幅,起始值和结束值相等时它们是相等的。 Eg 例如

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

Try assertItemsEqual , (in the docs ): 尝试assertItemsEqual ,(在文档中 ):

class MyTestCase(unittest.TestCase):
    def test_mytest(self):
        a = (0,1,2,3,4)
        self.assertItemsEqual(a, range(0,4))

Another way to do it: 另一种方法:

ranges_equal = str(a)==str(b)

The string representation indicates the start, end and step of ranges. 字符串表示指示范围的开始,结束和步骤。

This question makes me think that perhaps Python should provide a way to get these attributes from the range object itself! 这个问题让我觉得Python应该提供一种从范围对象本身获取这些属性的方法!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM