Python效率:列表与元组

时间:2011-05-19 18:52:44

标签: python python-2.7 optimization python-2.6

我有大量的基础对象。

这些基础对象将被放入集合中,这些集合将被包围:排序,截断等。

不幸的是, n 足够大,内存消耗稍微令人担忧,速度越来越快。

我的理解是元组的内存效率稍高,因为它们是经过重复数据删除的。

无论如何,我想知道Python 2.6 / 2.7中列表与元组的cpu /内存权衡是什么。

7 个答案:

答案 0 :(得分:16)

如果你有一个元组和一个具有相同元素的列表,那么元组占用的空间更少。由于元组是不可变的,你不能对它们进行排序,添加它们等等。我建议你看this talk by Alex Gaynor,以便快速介绍何时选择Python中的数据结构。

更新:再考虑一下,您可能需要考虑优化对象的空间使用情况,例如,通过__slots__或使用namedtuple实例作为代理而不是实际对象。这可能会带来更大的节省,因为你有N个,并且(只有少数)它们出现的集合。 namedtuple尤其超级棒极了;看看Raymond Hettinger's talk

答案 1 :(得分:9)

正如其他人提到的元组是不可改变的。对元组进行排序(例如sorted(mytuple))会返回一个列表,然后您必须将其转换回元组。

要对元组进行排序(并保持元组),您必须这样做:

mytuple = (3,2,1)
mysortedtuple = tuple(sorted(mytuple))

要对列表进行排序,您必须执行此操作:

mylist = [3,2,1]
mylist.sort()

因为你没有投射和重新投射,所以在这种情况下,后者更有效率。

除非你有充分的理由,否则不要挂在列表上使用元组。如果您需要排序数据,那么除非首先以这种方式创建元组,否则元组不是必须的。当元素包含的数据不会更改时(例如,在运行时加载的配置设置或已经处理的数据),元组会表现出色。

考虑到您提到您正在处理大型数据集,您可能希望通过列表和元组上的生成器和迭代器来查看函数式编程样式。这样你就不会穿梭并创建新的容器,而只是链接迭代操作以获得最终结果。

进一步阅读:

答案 2 :(得分:4)

集合中的基本对象(平均,最小,最大)数是多少?

元组是“重复数据删除”而列表不是?您认为“重复数据删除”在这种情况下意味着什么?

列表确实占用了比元组更多的内存,因为额外的内存是在列表将增长的假设下分配的,并且每次执行large_list.append()时你绝对不希望realloc()内存。但是在32位机器上,额外列表元素的分摊成本是指针为4个字节,元素本身为N个字节,额外内存不超过4个字节。对于浮点数,N是16个字节。这意味着浮点数列表每个额外浮点数最多需要24个字节,而元组则需要20个字节。 N == 100的“基础对象”给出108与104的比较。如果在两个集合中引用基础对象,则58与54相比。你的N有多大?

建议:将您的收藏保留为列表。专注于:

  • 确保您的基础对象具有内存效率

  • 在可能的情况下使用generator和itertools goodies而不是临时列表

  • 如果您无法避免使用临时列表,请确保它们不再被立即丢弃,不再需要它们,即不要等到创建方法返回;

  • 。尽快使用明确的del

答案 3 :(得分:3)

除了所有这些建议之外,您可能会发现numpy将满足您的需求。如果你的对象是numpy默认处理的东西(整数,本机C类型等)那么这将是理想的。您也可以使用带有自定义对象的numpy数组,但这可能比它的价值更多。

答案 4 :(得分:2)

你不能以同样的方式使用它们。元组是不可变的,不支持追加,排序等(在元组上调用sorted产生一个列表,依此类推)。元组与列表完全不同,因此任何性能比较都没有意义。

答案 5 :(得分:1)

您无法对不可变对象进行排序 - 即在对元组进行排序时,您将始终创建一个新元素。

答案 6 :(得分:1)

至少有两个与您相似的现有问题,答案(或其中的链接)可能对您有用。总结一下:让类型的特征(可变与不可变,异构与同类)而非性能指导您的决策,因为性能/效率差异很小。

<强> What's the difference between list and tuples in Python?
What are differences between List, Dictionary and Tuple in Python?