python教程—为什么range(0) == range(2,2,2)在python3中为真?-Python实用宝典

# python教程—为什么range(0) == range(2,2,2)在python3中为真?

```>>> r1 = range(0)
>>> r2 = range(2, 2, 2)
>>> r1 == r2
True
```

### range对象很特殊:

Python将把range对象作为 sequence 。本质上的意思是，这个比较并不计算，它们如何表示一个给定的序列，而是，它们表示什么

start、stop和step参数完全不同的事实在这里没有什么区别，因为在展开时，它们都表示一个空列表:

```list(range(0))  # []
```

```list(range(2, 2, 2)) # []
```

```range(1, 5, 100) == range(1, 30, 100)
```

### 不，range对象是真的特殊:

```r0 = range(1, 1000000)
r1 = range(1, 1000000)

l0 = list(r0)
l1 = list(r1)
```

```%timeit r0 == r1
The slowest run took 28.82 times longer than the fastest. This could mean that an intermediate result is being cached
10000000 loops, best of 3: 160 ns per loop
```

```%timeit l0 == l1
10 loops, best of 3: 27.8 ms per loop
```

```/* r0 and r1 are pointers to rangeobjects */

/* Check if pointers point to same object, example:
>>> r1 = r2 = range(0, 10)
>>> r1 == r2
obviously returns True. */
if (r0 == r1)
return 1;

/* Compare the length of the ranges, if they are equal
the checks continue. If they are not, False is returned. */
cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
/* Return False or error to the caller
>>> range(0, 10) == range(0, 10, 2)
fails here */
if (cmp_result != 1)
return cmp_result;

/* See if the range has a lenght (non-empty). If the length is 0
then due to to previous check, the length of the other range is
equal to 0. They are equal. */
cmp_result = PyObject_Not(r0->length);
/* Return True or error to the caller.
>>> range(0) == range(2, 2, 2)  # True
(True) gets caught here. Lengths are both zero. */
if (cmp_result != 0)
return cmp_result;

/* Compare the start values for the ranges, if they don't match
then we're not dealing with equal ranges. */
cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
/* Return False or error to the caller.
lens are equal, this checks their starting values
>>> range(0, 10) == range(10, 20)  # False
Lengths are equal and non-zero, steps don't match.*/
if (cmp_result != 1)
return cmp_result;

/* Check if the length is equal to 1.
If start is the same and length is 1, they represent the same sequence:
>>> range(0, 10, 10) == range(0, 20, 20)  # True */
one = PyLong_FromLong(1);
if (!one)
return -1;
cmp_result = PyObject_RichCompareBool(r0->length, one, Py_EQ);
Py_DECREF(one);
/* Return True or error to the caller. */
if (cmp_result != 0)
return cmp_result;

/* Finally, just compare their steps */
return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
```

​Python实用宝典 (pythondict.com)