How can I enable xrange in Python 3 for portability?
Asked Answered
U

1

7

I wrote a script which I wanted to enable for both Python 2 and Python 3.

After importing division and print_function from __future__, my only concern was that my range returns a whole array in Python 2, wasting time and memory.

I added the following 3 lines at the beginning of the script, as a workaround:

if sys.version_info[0] == 3:
    def xrange(i):
        return range(i)

Then, I only used xrange in my code.

Is there some more elegant way to do it rather than my workaround?

Uncork answered 15/6, 2016 at 11:38 Comment(4)
There are dedicated libraries to it for you, e.g. six.Disinterested
I don't want to download 3rd party librariesUncork
Is your script really so time- and memory-intensive that it matters?Node
I usually write the code for Python 3 (dict.items(), range(), ...) and accept that it may perform sub-optimally with Python 2. So far no-one ever complained because most of the time the memory overhead is negligible.Acutance
O
13

You can simplify it a bit:

if sys.version_info[0] == 3:
    xrange = range

I would do it the other way around:

if sys.version_info[0] == 2:
    range = xrange

If you ever want to drop Python 2.x support, you can just remove those two lines without going through all your code.

However, I strongly suggest considering the six library. It is the de-facto standard for enabling Python 2 and 3 compatibility.

from six.moves import range
Optical answered 15/6, 2016 at 11:49 Comment(4)
I totally agree that the other way you suggest seems more usable. It's actually making Python2's range act like Python3's range, instead of intoducing xrange to Python3 and leaving Python3's range different from Python2's rangeUncork
in python3 the second version gives an error, as there is an "if" statement which is not executed, but then range variable is considered undefined. This is frustrating. I switched to six but it would be actually more preferable to avoid using an additional package.Nugget
@SergeyDovgal I just verified that the second version works as expected in Python 3.6.3. Or do you mean that you get an error in your IDE?Optical
@DanielHepper You are right, I just tried it in an interpreter and it works. However, I recall that the error obtained was related to code launched after installation script. Essentially I got "UnboundLocalError: local variable referenced before assignment", but I need to explain how to reproduce it. I will recall and describe a bit after.Nugget

© 2022 - 2024 — McMap. All rights reserved.