Python 最快的'structure'访问实现



我有一个数据结构,它由固定数量的字段和一个递归函数组成,该函数对这些结构的列表进行一些处理。在每次迭代中,该函数访问某个特定的列表元素(数据结构),分析其所有字段,并(基于字段值)通过删除或添加新的数据结构元素来修改列表。

我想知道实现此数据结构的最有效方法是什么?我想最敏感的方面是创建新结构和访问结构字段。我对具有 10 个字段的结构进行了一些测试:

  1. 以列表形式实现:
print("List")
def list_f ():
l = [1,2,3,4,5,6,7,8,9,10]
a1 = l[0]
a2 = l[1]
a3 = l[2]
a4 = l[3]
a5 = l[4]
a6 = l[5]
a7 = l[6]
a8 = l[7]
a9 = l[8]
a10 = l[9]
print(timeit("list_f()", "from __main__ import list_f"))

输出:

List
0.4056466743350029
  1. 实现为字典:
print("Dict")
def dict_f ():
d = {"1":1, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10}
a1 = d["1"]
a2 = d["2"]
a3 = d["3"]
a4 = d["4"]
a5 = d["5"]
a6 = d["6"]
a7 = d["7"]
a8 = d["8"]
a9 = d["9"]
a10 = d["10"]
print(timeit("dict_f()", "from __main__ import dict_f"))

输出:

Dict
0.6061008963733912
  1. 作为一个类实现:
print("Class")
class C (object):

def __init__(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10):
self.a1 = a1
self.a2 = a2
self.a3 = a3
self.a4 = a4
self.a5 = a5
self.a6 = a6
self.a7 = a7
self.a8 = a8
self.a9 = a9
self.a10 = a10
def class_f ():
c = C(1,2,3,4,5,6,7,8,9,10)
a1 = c.a1
a2 = c.a2
a3 = c.a3
a4 = c.a4
a5 = c.a5
a6 = c.a6
a7 = c.a7
a8 = c.a8
a9 = c.a9
a10 = c.a10
print(timeit("class_f()", "from __main__ import class_f, C"))

输出:

Class
1.2926895800046623

在我看来,列表是最有效的解决方案。您知道我可以尝试的任何其他实现,或者这些执行时间如何取决于结构字段的数量和类型吗?

编辑:

澄清一下,字段没有相同的类型(我只是在示例中使用了所有int-s),会有一些字符串,一些对象句柄等等...... 我永远不必即时修改字段。我知道在创建结构时希望它们具有哪些值,因此我将初始化它们并将结构插入到列表中。该函数仅读取这些值,并在完成后从列表中删除整个结构(并选择性地创建全新的结构并将其插入到输入列表中)。我是定义结构和函数的人,因此我可以调整函数以有效地处理任何实现。

如果您事先知道所需元素的位置,列表是有效的。字典有一个优势,如果你有一个键,你想访问一个值,这可以在恒定的时间内完成。列表访问也是一种线性时间操作,但在未知位置的情况下查找则不是,因为它需要遍历元素,直到找到正确的元素。

根据您的描述,我会说字典将是最清晰(如代码清晰度)的结构。

问题的答案取决于需要执行的操作以及要存储在容器中的数据类型。 对于您给出的示例,list是最有意义的。

假设你的观点是加速你的代码,你的替代方案是使用矢量化。例如,如果您要对每个元素执行相同的操作,并且元素是数字,那么您可以使用一个numpy.ndarray,该将使用矢量化方法来执行操作。 避免正常的 python 循环将大大减少执行时间。

列表是可编辑的对象,元组不是,字典是基于键的无序数据结构,而不是基于索引的列表和元组。谈到性能,元组和列表比字典略快,但可读性很重要。因此,如果该值具有含义(也许a1是某物的高度,a2是宽度,a3是房间中的蛇的数量等等),您应该考虑使用字典。如果它们是过去 10 小时的 BTC 价格(一个含义是所有值),您可以使用列表。元组使用不多。

经过一些额外的测试,我发现,正如@{bruno desthuilliers}所建议的那样,元组提供了最短的访问时间,因此以这种方式实现它。

最新更新