在Python 3.4中提高大型字典的速度

牵连

因此,我正在研究具有1000万个键的字典,我的任务是让它在3秒钟内(在Intel 2.4 GHz上)工作。我尝试对代码进行性能分析,而while循环有很多成功之处,但是我想不出一种方法来使我的代码在没有它的情况下运行得更快。有没有一种方法可以改善我的代码以使其更快地工作?

该代码应该(并且这样做,但是太慢)创建一个字典,其中的键都是从2到999999的整数,并且值是由序列模式制成的列表的长度。模式是:如果整数是偶数,则将其除以2,如果整数是奇数且大于1,则将其乘以3并加1。这一直持续到达到数字1。

示例:3-> 10-> 5-> 16-> 8-> 4-> 2->1。此列表的长度是8。

代码:

import time
start = time.clock()

first = 2
last = 1000000

def function1(n,d):
    if n/2 in d:
        d[n] = d[n/2] + 1
    if n not in d:
        d[n] = 0
        temp = n
        while temp > 1:
            if temp%2 == 0:
                temp /= 2
                d[n] += 1
            else:
                temp = 3*temp + 1
                d[n] += 1
            if temp in d:
                d[n] += d[temp]
                break
    return d[n]

d={}
d[1]=1
d={key: function1(key,d) for key in range(first,last)}

print(time.clock() - start)
马丁·彼得斯(Martijn Pieters)

在我的系统上,您的代码确实耗时超过3秒(在最近的2.3 GHz Intel Core i7 Macbook Pro上使用Python 3.4)。

我可以通过使用局部变量并避免两次构建字典,在3秒内(减少至2.65秒,减少12%)得到它:

def function1(n,d):
    if n/2 in d:
        d[n] = d[n/2] + 1
        return
    if n not in d:
        length = 0
        temp = n
        while temp > 1:
            if temp%2 == 0:
                temp //= 2
            else:
                temp = 3*temp + 1
            length += 1
            if temp in d:
                length += d[temp]
                break
        d[n] = length

d={1: 1}
for key in range(first,last):
    function1(key, d)

请注意,我使用局部length变量,而不是一直读取长度d[n]Python中的局部变量存储在C数组中,从而避免了必须对键进行哈希处理并进行查找(可能包括哈希冲突)的情况。

我从/(浮点除法)切换//(整数除法); 当您感兴趣的只是整数结果时,无需处理小数点。

如果在字典中找到,我也会返回n/2n not in d测试成功没有意义,因为我们刚刚添加d[n]了测试。

词典理解是完全多余的,function1()已经d就地更改,因此构建新词典来替换现有结果毫无意义。

下一步是利用temp您刚刚计算序列一开始,3您需要计算其他几个值。所有这些都可以存储在d一旦你完成,所以你不必重新计算序列1051684 两种

def function1(n,d):
    if n not in d:
        length = 0
        seen = []
        while n > 1:
            seen.append(n)
            if n % 2 == 0:
                n //= 2
            else:
                n = 3 * n + 1
            length += 1
            if n in d:
                length += d[n]
                break
        for num in seen:
            d[num] = length
            length -= 1

3需要8个步骤,但是我们可以存储7个10,6个5等。

if n/2 in d完全放弃了测试,while循环已经解决了这种情况。由于n在该if n not in d区块中不再需要该标记,因此我temp完全放弃了,然后继续n

现在整个测试仅需1.75秒。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何提高大型数据集中Python计算的速度?

来自分类Dev

如何在Python中提高大数模乘法的效率

来自分类Dev

从字典python 3的列表中提取数据

来自分类Dev

Python 3中的字典理解

来自分类Dev

通过Python中的大型列表进行计数时提高速度/性能

来自分类Dev

在Python 3中相乘大型矩阵

来自分类Dev

python 3保存字典

来自分类Dev

Python 3 字典的值

来自分类Dev

提高R中3个循环的速度

来自分类Dev

Python 3-从嵌套字典的键中提取值

来自分类Dev

在python 3中从csv文件创建字典

来自分类Dev

在python 3中创建嵌套字典

来自分类Dev

字典在python 3中不可排序?

来自分类Dev

字典python 3中的数据插值

来自分类Dev

在python 3中创建嵌套字典

来自分类Dev

Python 3中字典的映射长度

来自分类Dev

替换字典中的字符 - Python 3

来自分类Dev

在 Python 3 中打印字典

来自分类Dev

Python:在类中提高欧几里得距离计算的速度

来自分类Dev

我该如何提高Python 3中的套接字性能?

来自分类Dev

Python 3中的TabError

来自分类Dev

Python 3中的循环

来自分类Dev

Python 3中的Unicode()

来自分类Dev

python 3 中的缩进

来自分类Dev

字典清单Python3

来自分类Dev

如何在处理大型文件时提高Sublime Text 3的速度

来自分类Dev

python 3中的S3BotoStorage

来自分类Dev

在Python3中使用“不在”的速度快于在Python3中使用“在”的速度吗?

来自分类Dev

大型浮点的Python3停止除法