前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个Python3和Python2的range差异

一个Python3和Python2的range差异

作者头像
用户1416054
发布2018-08-02 12:03:50
3100
发布2018-08-02 12:03:50
举报
文章被收录于专栏:JackeyGao的博客

一个Python3和Python2的range差异

Posted December 20, 2017

Python 3 中执行100000000 in range(100000001)会比Python 2快的非常多。

Bash

代码语言:javascript
复制
$ time python -c "100000000 in range(100000001)"
python -c "100000000 in range(100000001)"  4.00s user 1.47s system 99% cpu 5.527 total
$ time python3 -c "100000000 in range(100000001)"
python3 -c "100000000 in range(100000001)"  0.04s user 0.01s system 86% cpu 0.055 total

如果把量级增高, Py2会出现 MemoryError, Py3也会以非常快的速度执行。所以猜测Py3没有生成列表.

先看下两个方法的区别.

Python2

Python

代码语言:javascript
复制
>>> dir(range)
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

Python3

Python

代码语言:javascript
复制
>>> dir(range)
['__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop']

可以看出有部分方法和属性的区别, 很明显Py3增强了 range 函数. 其实需要注意的是__contains__, 这个函数支持了innot in运算符, 所以完全可以通过,判断100000000是否大于开始数字和结束数字即可完成innot in运算.

如何用Py2实现Py3的range

注意代码中的__contains__方法.

Python

代码语言:javascript
复制
class my_range(object):
    def __init__(self, start, stop=None, step=1):
        if stop is None:
            start, stop = 0, start
        self.start, self.stop, self.step = start, stop, step
        if step < 0:
            lo, hi = stop, start
        else:
            lo, hi = start, stop
        self.length = ((hi - lo - 1) // abs(step)) + 1

    def __iter__(self):
        current = self.start
        if self.step < 0:
            while current > self.stop:
                yield current
                current += self.step
        else:
            while current < self.stop:
                yield current
                current += self.step

    def __len__(self):
        return self.length

    def __getitem__(self, i):
        if i < 0:
            i += self.length
        if 0 <= i < self.length:
            return self.start + i * self.step
        raise IndexError('Index out of range: {}'.format(i))

    def __contains__(self, num):
        if self.step < 0:
            if not (self.stop < num <= self.start):
                return False
        else:
            if not (self.start <= num < self.stop):
                return False
        return (num - self.start) % self.step == 0

整理翻译于StackoverFlow

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一个Python3和Python2的range差异
    • 如何用Py2实现Py3的range
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档