0

Everyone seems to claim that xrange returns a generator but it really is its own thing:

>>> xrange(10)
xrange(10)
>>> xrange(10).__bases__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'xrange' object has no attribute '__bases__'

What I don't understand is how xrange lets you check membership.

>>> a = xrange(10)
>>> 4 in a
True
>>> 4 in a
True

If this was a real generator, the second check would fail since we have already iterated through the 4.

>>> def mygen():
...     num = 0
...     while num < 100:
...             yield num
...             num += 1
...
>>>
>>> mygen()
<generator object mygen at 0x100618b40>
>>> list(mygen())
[0, ..., 99]
>>> x = mygen()
>>> 4 in x
True
>>> 4 in x
False

There seems to be something special about xrange that lets it do membership properly, as if it overrides __contains__.

4

1 回答 1

1

It turns out, xrange is indeed not a true <type 'generator'>.

At the cython level there is a generator that powers the range logic, but there is also a range_contains_long function which does the comparison, bypassing iteration of the generator.

Therefore, to call xrange a generator is slightly misleading.

于 2019-12-06T18:59:16.843 回答