4

I am aware of the downsides of range in Python 2.x (it creates a list which is inefficient for large ranges) and it's faster iterator counterpart xrange. In Python 3.x however, range is an iterator and xrange is dropped. Is there a way to write these two loops written with Python 2.x and Python 3.x in such a way that the code will be portable and will use iterators?

# Python 2.x
for i in xrange(a_lot):
    use_i_in_someway(i)

# Python 3.x
for i in range(a_lot):
    use_i_in_someway(i)

I am aware that one may do something like

if(platform.python_version_tuple()[0] == '3'):
    xrange = range

but I was thinking for something less hack-ish and not custom-built.

dmg
  • 7,438
  • 2
  • 24
  • 33
  • related: [`xrange(2**100)` -> OverflowError: long int too large to convert to int](http://stackoverflow.com/questions/1482480/xrange2100-overflowerror-long-int-too-large-to-convert-to-int) – jfs Feb 14 '13 at 10:19

2 Answers2

2

One alternative is to use the Six module, that provides simple utilities for wrapping over differences between Python 2 and Python 3. It is intended to support codebases that work on both Python 2 and 3 without modification.

root
  • 76,608
  • 25
  • 108
  • 120
  • @DJV -- Yes, but I don't think there really is a non custom one :( – root Feb 15 '13 at 10:30
  • It's still the answer that comes closest to what I want. I'll wait for a couple of days and accept it if nothing better comes :) – dmg Feb 15 '13 at 10:37
1

Don't worry about xrange(), 2to3 simply converts it to range(). But if you are writing a portable code, then a good idea would be creating e.g. compat.py file in which you import cross-python functionality. E.g. see the pymongo source: https://github.com/mongodb/mongo-python-driver/blob/master/bson/py3compat.py

Zaur Nasibov
  • 22,280
  • 12
  • 56
  • 83
  • 1
    But that assumes the program will be *translated* into a version optimized for Python 3, while DJV sounds as if the goal is to keep the *same* program running optimally under both. – unwind Feb 14 '13 at 09:41
  • the question asks for the code which will work across both 2/3 w/o any conversion – MoveFast Feb 14 '13 at 09:42
  • @unwind, a great intention indeed, but that does not work well in large projects. Highly recommend reading Armin Ronacher's article: http://lucumr.pocoo.org/2011/12/7/thoughts-on-python3/ – Zaur Nasibov Feb 14 '13 at 09:42
  • @unwind the `compat.py` is a good approach for hiding some differences, but it is pretty much the same approach as I mention (define `xrange` if Python 3.x) or define a custom iterator, say `efficient_range` based on the version. IMO `compat.py` should be used when it comes to custom-built functionality that is well hidden within a class and not for such basic functionality. – dmg Feb 14 '13 at 10:04