【发布时间】:2014-05-10 15:07:58
【问题描述】:
我有一个奇怪的请求,我希望以最高效率解决;我有两个列表list_1 和list_2,它们的长度相同,并且都只包含大于或等于0 的整数。我想创建一个新列表list_3,这样每个元素i 都是来自list_1 和list_2 的位置i 的元素之和。在 python 中,这就足够了:
list_3 = [list_1[i] + list_2[i] for i in range(len(list_1))]
但是,有一个问题。对于每个i 使得0 <= i < len(list_1),如果位置i 的项目(即list_1[i])为0,那么list_1[i] 和list_2[i] 的总和应该也为零 .
最有效的方法是什么?我必须在包含 323 个元素的列表上执行此操作,并且它需要用于游戏,因此它应该能够轻松地每秒运行 60 次,同时允许大量额外的时间来计算游戏中的其他事物。我想知道是否有任何花哨的 numpy 方法可以做到这一点,但我对 numpy 的了解还不够,无法确定。
编辑:
就简单地将两个元素相加而言,一些常见的表达式是:
list_3 = [list_1[i] + list_2[i] for i in range(len(list_1))]
list_3 = [sum(t) for t in zip(list_1, list_2)]
list_3 = numpy.add(list_1, list_2)
编辑 2:
我知道条件列表推导,但我想知道是否有比这更快的方法。
编辑 3:
以下是给出的一些方法的时间安排:
>>> import timeit
>>> setup='''
import random
list_1 = [random.randint(0, 323) for i in range(323)]
list_2 = [random.randint(0, 323) for i in range(323)]
'''
>>> timeit.timeit('list_3 = [list_1[i] + list_2[i] if list_2[i] else 0 for i in range(len(list_1))]', setup=setup, number=1)
6.005677381485953e-05
>>> timeit.timeit('list_3 = [x + y if y else 0 for x, y in zip(list_1, list_2)]', setup=setup, number=1)
3.604091037417601e-05
更快吗?
编辑 4:
以下是我需要此功能的解释:我正在开发一款视频游戏,该游戏需要一个不时检查键盘上某些键状态的系统。系统需要工作的方式是按键被按下的时间越长,该按键的计数器就增加得越高。释放该键后,计数器将设置回 0。这需要对所有键进行,而不仅仅是少数几个键。根据cProfile 的说法,与程序的其他部分相比,它目前是一个瓶颈。
这是生成键盘中每个键状态的代码(它使用pygame 来获取键状态):
class KeyState:
"""
An object representing the state of the keyboard input at a given frame.
The KeyState is a global replacement for pygame's event system (or
pygame.keys.get_pressed()). It provides a simple interface for updating
and retreiving the states of keys in real time.
To retreive and store the current key information, simply call
the update() method. To retreive the given information about a
key, use the get_state(key) method where key is any pygame key
(i.e. pygame.K_RSHIFT, etc.).
"""
def __init__(self):
self.current_frame = pygame.key.get_pressed()
def update(self):
"""
Retreive the current key state data.
"""
new_frame = pygame.key.get_pressed()
self.current_frame = [state + new_frame[i] if new_frame[i] else 0 for i, state in enumerate(self.current_frame)]
def get_state(self, key, strict=True):
"""
Retreive the current state of a given key.
>= 1 - Pressed
0 - Unpressed
"""
try:
return self.current_frame[key]
except KeyError:
if strict:
raise
【问题讨论】:
-
请指定“位置 i 的项目”
-
已编辑以更好地描述“位置 i 的项目”的含义。
-
谢谢!为了了解性能要求,您是否愿意详细说明您需要计算什么以及为什么它会成为这样的瓶颈?也许您需要一个 numpy 解决方案,而不是他们在下面展示的列表理解魔法。
-
如果这严重是您的瓶颈?我怀疑优化一项会占用 60fps 时间预算的 0.4% 的操作会产生什么不同。
-
所以我太偏执了?请告诉我是不是因为我以前在不必要的地方容易进行微优化。我只是担心,因为到目前为止,其他所有事情似乎单独花费的时间要少得多。