12
\$\begingroup\$

A common idiom that I use for Python2-Python3 compatibility is:

try:
 from itertools import izip
except ImportError: #python3.x
 izip = zip

However, a comment on one of my Stack Overflow answers implies that there may be a better way. Is there a more clean way to accomplish this?

Peilonrayz
44.4k7 gold badges80 silver badges157 bronze badges
asked May 16, 2013 at 22:53
\$\endgroup\$
2
  • \$\begingroup\$ Perhaps the commenter meant to use the import to shadow zip? I.e., try: from itertools import izip as zip; except ImportError: pass. (Please excuse the lack of newlines.) \$\endgroup\$ Commented May 16, 2013 at 23:10
  • \$\begingroup\$ Perhaps -- (I knew about that one). I was just wondering if there was some magic with __import__ that I didn't know about or something. \$\endgroup\$ Commented May 16, 2013 at 23:14

3 Answers 3

14
\$\begingroup\$

Not sure this is really an answer, or I should elaborate on my comment, and in hindsight probably not even a very good comment anyway, but:

Firstly, you can just simplify it to:

try:
 from itertools import izip as zip
except ImportError: # will be 3.x series
 pass

What I was thinking about was:

From 2.6 you can use as per the docs:

from future_builtins import map # or zip or filter

You do however then have the same problem of ImportError - so:

try:
 from future_builtins import zip
except ImportError: # not 2.6+ or is 3.x
 try:
 from itertools import izip as zip # < 2.5 or 3.x
 except ImportError:
 pass

The advantage of using future_builtin is that it's in effect a bit more "explicit" as to intended behaviour of the module, supported by the language syntax, and possibly recognised by tools. (削除) For instance, I'm not 100% sure, but believe that the 2to3 tool will re-write zip correctly as list(zip(... in this case, while a plain zip = izip may not be... But that's something that needs looking in to. (削除ここまで)

Updated - also in the docs:

The 2to3 tool that ports Python 2 code to Python 3 will recognize this usage and leave the new builtins alone.

answered May 17, 2013 at 0:05
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Ahh ... I didn't actually know about future_builtins. It seems a little silly that they don't have that in python3 though. I don't know why they didn't do something like from __future__ import zip instead. That would have made sense to me. Anyway, thanks for the explanation. \$\endgroup\$ Commented May 17, 2013 at 1:16
  • \$\begingroup\$ I also think it's silly that 2to3 recognizes the usage of future_builtins yet leaves the from future_builtins import whatever statement(s) in the output. \$\endgroup\$ Commented Jun 25, 2013 at 19:19
3
\$\begingroup\$

If you are trying to make Python 2.x code compatible with Python 3.x you should look at six:

http://pythonhosted.org/six/#module-six.moves

answered May 20, 2013 at 23:09
\$\endgroup\$
1
  • \$\begingroup\$ Yeah, six is nice. Generally, if it's simple enough though, I tend to prefer to avoid the extra dependency. \$\endgroup\$ Commented May 20, 2013 at 23:50
3
\$\begingroup\$

This is roughly twice as fast as using a try/except:

import itertools
zip = getattr(itertools, 'izip', zip)
200_success
145k22 gold badges190 silver badges478 bronze badges
answered Jun 20, 2017 at 17:48
\$\endgroup\$
2
  • \$\begingroup\$ I find this claim hard to believe ... getattr works by catching the AttributeError and substituting the default value. Admittedly, that's implemented in C so it might be slightly faster, but I find it hard to believe that there's a factor of 2. I also find it hard to believe that the time would matter in the real world if you have this at the top-level of your module... Finally, this is possibly the cleanest way to write it that I've seen. Kudos for that :-). \$\endgroup\$ Commented Jun 21, 2017 at 3:28
  • \$\begingroup\$ @mgilson: Use timeit and test it yourself. I thought it might be faster, but I didn't think ~2x. \$\endgroup\$ Commented Jun 22, 2017 at 11:38

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.