Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中两个项目列表求和的最快方法_Python_List_Numpy - Fatal编程技术网

python中两个项目列表求和的最快方法

python中两个项目列表求和的最快方法,python,list,numpy,Python,List,Numpy,我有一个奇怪的要求,我希望以最大的效率来解决;我有两个列表list_1和list_2,它们的长度相同,并且都只包含大于或等于0的整数。我想创建一个新的列表list_3,这样每个元素I都是list_1和list_2中位于I位置的元素之和。在python中,这就足够了: list_3=[list_1[i]+list_2[i]表示范围内的i(len(list_1))] 然而,有一个陷阱。对于每个i,这样0就可以在Python3.x中很好地工作 list3 = [x+y if x and y else

我有一个奇怪的要求,我希望以最大的效率来解决;我有两个列表
list_1
list_2
,它们的长度相同,并且都只包含大于或等于0的整数。我想创建一个新的列表
list_3
,这样每个元素
I
都是
list_1
list_2
中位于
I
位置的元素之和。在python中,这就足够了:

list_3=[list_1[i]+list_2[i]表示范围内的i(len(list_1))]


然而,有一个陷阱。对于每个
i
,这样
0就可以在Python3.x中很好地工作

list3 = [x+y if x and y else 0 for x, y in zip(list1, list2)]
或者,如果您使用的是Python 2.x:

import itertools as it
list3 = [x+y if x and y else 0 for x, y in it.izip(list1, list2)]
您可以使用:

对于Numpy(您的问题已标记),您可以使用:

或者,如果您更喜欢函数而不是lambda:

>>> def vector(e1, e2):
...    if e1 and e2: return e1+e2
...    return 0
...
>>> vector_func=np.vectorize(vector)
>>> vector_func(a1,a2)
array([ 2,  4,  6,  0,  0, 11, 13])
使用计时代码,矢量化解决方案速度更快:

import timeit
import numpy as np
import random

a1=np.array([random.randint(0, 323) for i in range(323)])
a2=np.array([random.randint(0, 323) for i in range(323)])
vector_func=np.vectorize(lambda e1, e2: e1+e2 if e1 and e2 else 0)

n=10000

setup='''
from __main__ import a1, a2, vector_func
'''
print timeit.timeit('a3 = [a1[i] + a2[i] if a2[i] else 0 for i in range(len(a1))]', setup=setup, number=n)
print timeit.timeit('a3 = [x + y if y else 0 for x, y in zip(a1, a2)]', setup=setup, number=n)
print timeit.timeit('a3=vector_func(a1,a2)', setup=setup, number=n)
印刷品:

2.25640797615
1.97595286369
0.993543148041

与纯Python相比,Numpy速度较慢,不过如果您只有int,并且没有其他理由使用Numpy的话

下面是一个示例,它说明了正则和和条件和,使用:

list3 = [x + y for x, y in zip(list1, list2)]

关于速度,任何明智的解决方案都会执行相同的操作——尽管为了节省内存,如果代码的其余部分允许,可以考虑使用生成器表达式而不是列表。您应该选择最清晰的内容。

设置:

import numpy as np
import random
list_1 = [random.randint(0, 323) for i in range(323)]
list_2 = [random.randint(0, 323) for i in range(323)]
array_1 = np.random.randint(0,323,323)
array_2 = np.random.randint(0,323,323)
原定时间:

%timeit list_3 = [list_1[i] + list_2[i] if list_2[i] else 0 for i in range(len(list_1))]
10000 loops, best of 3: 62.8 µs per loop

%timeit list_3 = [list_1[i] + list_2[i] if list_2[i] else 0 for i in range(len(list_1))]
10000 loops, best of 3: 62.3 µs per loop
奥斯卡·洛佩兹的解决方案:

%timeit list3 = [x+y if x and y else 0 for x, y in zip(list_1, list_2)]
10000 loops, best of 3: 60.7 µs per loop

import itertools as it

%timeit list3 = [x+y if x and y else 0 for x, y in it.izip(list_1, list_2)]
10000 loops, best of 3: 50.5 µs per loop
Dawg的
np.矢量化
解决方案:

vector_func=np.vectorize(lambda e1, e2: e1+e2 if e1 and e2 else 0)

%timeit vector_func(array_1,array_2)
10000 loops, best of 3: 121 µs per loop
%timeit out = array_1 + array_2; out[(array_1==0) & (array_2==0)] = 0
100000 loops, best of 3: 11.1 µs per loop
numpy解决方案:

vector_func=np.vectorize(lambda e1, e2: e1+e2 if e1 and e2 else 0)

%timeit vector_func(array_1,array_2)
10000 loops, best of 3: 121 µs per loop
%timeit out = array_1 + array_2; out[(array_1==0) & (array_2==0)] = 0
100000 loops, best of 3: 11.1 µs per loop
这里的问题是,如果您选择使用列表,numpy解决方案实际上会更慢

%%timeit
array_1 = np.array(list_1)
array_2 = np.array(list_2)
out = array_1 + array_2
out[(array_1==0) & (array_2==0)] = 0
10000 loops, best of 3: 84.8 µs per loop
numpy解决方案将是最快的,但您需要在一开始就使用numpy阵列

按键按下的时间越长,所述按键的计数器增加的越高

除非你的用户有300个手指,否则他们一次最多只能按10个键。您可以注册keydown和keyup事件;当按键按下时,在数组上保存帧计数器或time()/clock()的返回值;当一个键启动或需要查找该键的当前值时,减去差值。这将使循环的数量减少到10个左右,而不是300个。请注意,根据系统的不同,time()/clock()可能是一个系统调用,可能会比较慢,因此最好使用帧计数器

counter = 0
keys = {}
while True:
    for event in pygame.event.get() :
        if event.type == pygame.KEYDOWN :
            keys[event.key] = counter
        elif event.type == pygame.KEYUP :
            diff[event.key] = keys.pop(event.key) - counter
    counter += 1

但我非常怀疑这是否是您游戏的瓶颈。

请指定编辑的“位置I处的物品”,以便更好地描述我所说的“位置I处的物品”。谢谢!为了理解性能需求,您是否愿意详细说明您需要计算什么以及它为什么会成为瓶颈?也许你需要一个numpy解决方案,而不是下面的列表。如果这严重影响了你的瓶颈?我怀疑优化一个占你60帧的时间预算0.4%的操作会有什么不同。所以我太偏执了?请告诉我是否是因为我以前在不必要的地方进行过微优化。我只是担心,因为到目前为止,所有其他的事情似乎都需要更少的时间。如果
list2
中的项为零,那么这并不等于0。如果t[0],那么应该是
sum(t)!=0和t[1]!=0其他0
为了处理问题中的奇怪捕获。你们是对的,我忽略了捕获。现在修好了
vector_func=np.vectorize(lambda e1, e2: e1+e2 if e1 and e2 else 0)

%timeit vector_func(array_1,array_2)
10000 loops, best of 3: 121 µs per loop
%timeit out = array_1 + array_2; out[(array_1==0) & (array_2==0)] = 0
100000 loops, best of 3: 11.1 µs per loop
%%timeit
array_1 = np.array(list_1)
array_2 = np.array(list_2)
out = array_1 + array_2
out[(array_1==0) & (array_2==0)] = 0
10000 loops, best of 3: 84.8 µs per loop
counter = 0
keys = {}
while True:
    for event in pygame.event.get() :
        if event.type == pygame.KEYDOWN :
            keys[event.key] = counter
        elif event.type == pygame.KEYUP :
            diff[event.key] = keys.pop(event.key) - counter
    counter += 1