lifeng.luck
lifeng.luck

Reputation: 601

What's the difference in statements below to get a range?

When I read the Django tickets and pull requests, I find they have following changes:

They want to get a range about page numbers, And change from

return range(1, self.num_pages + 1) # 1

to:

return six.moves.range(1, self.num_pages + 1) # 2

then:

 return list(six.moves.range(1, self.num_pages + 1)) # 3

I am confusing what's difference between 1 and 3? And why not just this, is there any difference with 3?

 return list(range(1, self.num_pages + 1)) # 4

Upvotes: 2

Views: 1065

Answers (3)

stderr
stderr

Reputation: 8722

range in Python 2.X is constructs a new list. So, for example:

range(4) == [0, 1, 2, 3]

xrange in Python 2.X is an generator that lazily yields values equivalent to what would be returned by range without any of the memory overhead.

Python 3.X got rid of range with replaced it with xrange. The behavior of xrange is generally more efficient, but if you really need to construct a list using range you'll have to explicitly iterate it or use the list constructor.

range in Python 2.X returns a list. In Python 3.X:

>>> type(range(4))
<class 'range'>

To explicitly create a list with range in Python 3 just do:

list(range(4)) == [0, 1, 2, 3]

Or

my_list = [ x for x in range(4) ]

Upvotes: 1

wookie919
wookie919

Reputation: 3134

From the Python documentation:

Python 3 reorganized the standard library and moved several functions to different modules. Six provides a consistent interface to them through the fake six.moves module.

In the same page, it tells us that six.moves.range() calls xrange() for Python 2 and range() for Python 3. xrange() is very similar to range(), except that it returns an xrange object rather than a list. Thus the list() around the call to make it into a list.

It seems that the whole point of the change was to make the code work with both Python 2 and Python 3.

Upvotes: 4

jheld
jheld

Reputation: 148

Seems that this SO question may offer some guidance: six.moves.builtins.range is not consistent in Python 2 and Python 3, it certainly did for me. It looks like they made the change for efficiency sake.

Upvotes: 0

Related Questions