Python 如何更有效地编写此解决方案?

Python 如何更有效地编写此解决方案?,python,performance,python-2.7,Python,Performance,Python 2.7,该代码在a,b,c中找到最佳的元素三元组,从而使a[i]+b[j]+b[k]最大化,并且i+j+k=10保持首先,您可以更改循环的边界并去掉最里面的循环: import random a = [int(1000*random.random()) for i in xrange(10)] b = [int(1000*random.random()) for i in xrange(10)] c = [int(1000*random.random()) for i in xrange(10)] d

该代码在
a,b,c
中找到最佳的元素三元组,从而使
a[i]+b[j]+b[k]
最大化,并且
i+j+k=10
保持

首先,您可以更改循环的边界并去掉最里面的循环:

import random

a = [int(1000*random.random()) for i in xrange(10)]
b = [int(1000*random.random()) for i in xrange(10)]
c = [int(1000*random.random()) for i in xrange(10)]
d = dict()
for i in xrange(len(a)):
    for j in xrange(len(b)):
        for k in xrange(len(c)):
            if (i+j+k == 10):
                d[(i,j,k)] = a[i]+b[j]+c[k]

print max(d.values())

首先,您可以更改循环的边界并去掉最里面的循环:

import random

a = [int(1000*random.random()) for i in xrange(10)]
b = [int(1000*random.random()) for i in xrange(10)]
c = [int(1000*random.random()) for i in xrange(10)]
d = dict()
for i in xrange(len(a)):
    for j in xrange(len(b)):
        for k in xrange(len(c)):
            if (i+j+k == 10):
                d[(i,j,k)] = a[i]+b[j]+c[k]

print max(d.values())

将代码包装在函数中将提高可变查找速度,这样您就不需要第三个循环:

In [2]: %timeit original()
10000 loops, best of 3: 166 us per loop

In [3]: %timeit new()
10000 loops, best of 3: 36.1 us per loop
随机导入
def f(随机=随机。随机):
a=[int(1000*random())表示x范围内的i(10)]
b=[int(1000*random())表示x范围内的i(10)]
c=[int(1000*random())表示x范围内的i(10)]
d={}
对于x范围内的i(len(a)):
对于X范围内的j(透镜(b)-i):
k=10-i-j

如果0将代码包装在函数中将提高可变查找速度,则不需要第三个循环:

In [2]: %timeit original()
10000 loops, best of 3: 166 us per loop

In [3]: %timeit new()
10000 loops, best of 3: 36.1 us per loop
随机导入
def f(随机=随机。随机):
a=[int(1000*random())表示x范围内的i(10)]
b=[int(1000*random())表示x范围内的i(10)]
c=[int(1000*random())表示x范围内的i(10)]
d={}
对于x范围内的i(len(a)):
对于X范围内的j(透镜(b)-i):
k=10-i-j

如果0我认为缓存
random.random
查找可以显著提高性能

import random
def f(random=random.random):
    a = [int(1000*random()) for i in xrange(10)]
    b = [int(1000*random()) for i in xrange(10)]
    c = [int(1000*random()) for i in xrange(10)]
    d = {}
    for i in xrange(len(a)):
        for j in xrange(len(b)-i):
            k = 10 - i - j
            if 0 <= k < 10:
                d[i,j,k] = a[i]+b[j]+c[k]
    return max(d.values())
f()
随机导入
def():
rand=random.random
a=[int(1000*rand())表示x范围(10)]
b=[int(1000*rand())表示x范围(10)]
c=[int(1000*rand())表示x范围(10)]
d=dict()
对于X范围内的i(10):
对于X范围内的j(10-i):
k=10-i-j

如果0我认为缓存
random.random
查找可以显著提高性能

import random
def f(random=random.random):
    a = [int(1000*random()) for i in xrange(10)]
    b = [int(1000*random()) for i in xrange(10)]
    c = [int(1000*random()) for i in xrange(10)]
    d = {}
    for i in xrange(len(a)):
        for j in xrange(len(b)-i):
            k = 10 - i - j
            if 0 <= k < 10:
                d[i,j,k] = a[i]+b[j]+c[k]
    return max(d.values())
f()
随机导入
def():
rand=random.random
a=[int(1000*rand())表示x范围(10)]
b=[int(1000*rand())表示x范围(10)]
c=[int(1000*rand())表示x范围(10)]
d=dict()
对于X范围内的i(10):
对于X范围内的j(10-i):
k=10-i-j

如果0因为您没有实际使用
dict
的键,那么您可以更快地构建和迭代
列表。但是,由于除了调用
max
,您实际上也并没有对值进行任何操作,所以您可以在执行过程中跟踪最大值,而不构建和迭代任何内容

修改NPE的解决方案:

import random

def f():
    rand = random.random
    a = [int(1000*rand()) for _ in xrange(10)]
    b = [int(1000*rand()) for _ in xrange(10)]
    c = [int(1000*rand()) for _ in xrange(10)]
    d = dict()
    for i in xrange(10):
        for j in xrange(10 - i):
            k = 10 - i - j
            if 0 <= k < 10:
                d[(i,j,k)] = a[i]+b[j]+c[k]

    print max(d.values())

f()
不用说,首先使用PyPy而不是CPython比任何人建议的任何微优化都要大得多


对于一个真正的问题,当你有1000000个值而不是10个值时,这是一个糟糕的解决方法

首先,只需将值保存为
int32
值数组而不是Python
list
s,就可以大大降低内存使用率(从而缩短分页时间、缓存命中率等)。一旦你做到了这一点,你就可以把它放在100000x3
numpy.array
中。然后您只需要构建一个i+j+k==1000000的掩码数组,应用掩码,并在其中找到最大值。这会将所有循环移到C中,我猜它会快10-30倍。比使用Python进行微优化要多得多


但你可能想去另一个方向。你需要这些列表存在吗?如果你有一系列的数据被懒洋洋地生成/读取/随便什么,有没有一种方法可以做到这一点,而不必将整个内容读入内存?看起来你只需要两个完整的列表,如果你能控制第三个列表到达的顺序,就只需要一个。事实上,如果你能控制第三个的顺序,你只需要生成/读取它的前10%。

因为你实际上没有使用
dict
的键,你可以更快地构建和迭代
列表。但是,由于除了调用
max
,您实际上也并没有对值进行任何操作,所以您可以在执行过程中跟踪最大值,而不构建和迭代任何内容

修改NPE的解决方案:

import random

def f():
    rand = random.random
    a = [int(1000*rand()) for _ in xrange(10)]
    b = [int(1000*rand()) for _ in xrange(10)]
    c = [int(1000*rand()) for _ in xrange(10)]
    d = dict()
    for i in xrange(10):
        for j in xrange(10 - i):
            k = 10 - i - j
            if 0 <= k < 10:
                d[(i,j,k)] = a[i]+b[j]+c[k]

    print max(d.values())

f()
不用说,首先使用PyPy而不是CPython比任何人建议的任何微优化都要大得多


对于一个真正的问题,当你有1000000个值而不是10个值时,这是一个糟糕的解决方法

首先,只需将值保存为
int32
值数组而不是Python
list
s,就可以大大降低内存使用率(从而缩短分页时间、缓存命中率等)。一旦你做到了这一点,你就可以把它放在100000x3
numpy.array
中。然后您只需要构建一个i+j+k==1000000的掩码数组,应用掩码,并在其中找到最大值。这会将所有循环移到C中,我猜它会快10-30倍。比使用Python进行微优化要多得多


但你可能想去另一个方向。你需要这些列表存在吗?如果你有一系列的数据被懒洋洋地生成/读取/随便什么,有没有一种方法可以做到这一点,而不必将整个内容读入内存?看起来你只需要两个完整的列表,如果你能控制第三个列表到达的顺序,就只需要一个。事实上,如果你能控制第三个的顺序,你只需要生成/读取其中的前10%。

这看起来像是家庭作业。您可以消除内部循环,因为对于给定的
(i,j)
只有一个
k
。此外,您不需要dict,因为您根本不使用它的键-只需
生成a[i]+b[j]+c[k]
并在生成的生成器上调用
max
。为什么需要它来提高效率?它在我的笔记本电脑上运行不到半毫秒。@abarnert将10更改为1000000,看看现在需要多长时间。@0x90:但这是一个完全不同的问题。例如,停止分配三个1M元素列表,找到一种使用迭代器的方法。或者使用numpy。这看起来像h