专栏首页JackeyGao的博客一个Python3和Python2的range差异

一个Python3和Python2的range差异

一个Python3和Python2的range差异

Posted December 20, 2017

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

Bash

$ 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

>>> 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

>>> 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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 获取 zabbix 挂件数据(widget)

    Zabbix 有非常丰富的 API ,但没有 widget 的 API。 所以获取 widget 的数据需要通过模拟登录爬取网页的形式来做。虽然我们可以用一定的...

    用户1416054
  • Django小技巧11: 自定义链式Queryset Manager

    在 Django Model 中,Manager是与数据库交互的接口。默认情况下Manager可通过Model.objects属性使用。默认情况下, 每个 Mo...

    用户1416054
  • Django 自定义管理命令

    Django 提供了一组非常实用的命令, 可以通过django-admin.py和pytohn manage.py脚本调用. 关于这个Management Co...

    用户1416054
  • 如何用栈实现浏览器的前进和后退?

    这里先介绍一下栈的定义和实现,并介绍它的一些常用的应用,最后再简单实现一个简单的浏览器前进和后退的操作。

    材ccc
  • 【实战小项目】python开发自动化运维工具--批量操作主机

    有很多开源自动化运维工具都很好用如ansible/salt stack等,完全不用重复造轮子。只不过,很多运维同学学习Python之后,苦于没小项目训练,本篇演...

    用户1432189
  • Prioritized Experience Replay (DQN)——让DQN变得更会学习

    1.前言2.算法2.1 SumTree有效抽样2.2 Memory类2.3 更新方法对比结果

    CristianoC
  • 深度强化学习之DQN实战

    今天我们会将我们上一篇文章讲解的DQN的理论进行实战,实战的背景目前仍然是探险者上天堂游戏,不过在下一次开始我们会使用OpenAI gym的环境库,玩任何我们想...

    CristianoC
  • Python|520表白神器

    众所周知,5月20日为“520”情人节,这一天也是即将到来,大家都希望与自己的男神女神过一个浪漫的情人节。但是还有很多像小编这样的单身狗,不知道如何向自己的男神...

    算法与编程之美
  • 我的tkinter学习笔记4

    用户6367961
  • 箱线图(BoxPlot) App

    由于公司的Execl版本(v2010)偏低,没有画箱线图的功能,故我用python写了一小段程序,可以用来画箱线图。绘图库使用的还是matplotlib。

    用户6021899

扫码关注云+社区

领取腾讯云代金券