首页 > 解决方案 > 哪种序列类型更适合比较,为什么?(Python)

问题描述

我有一个条件将一个对象与其他几个对象进行比较,如下所示:

if 'a' in ('a','b','c','e'):

该序列是为此目的而创建的,并且在函数的其他任何地方都不存在。考虑到它们似乎都工作相同并且列表很短,将其分组为元组、列表或集合的优点和缺点是什么?哪个是惯用的?

标签: pythontypescomparisonsequence

解决方案


使用一套,直到你有充分的理由不这样做。(然后使用列表。)

我会认为一组更惯用。它更清楚地传达了含义,因为顺序无关紧要,只有成员资格。

需要明确的是,集合是一个集合,但不是“序列类型”(即使它是可迭代的),因为它在语义上是“无序的”。


为什么不使用一套?

集合只能包含可散列类型。而且,这很重要,当您询问集合中是否有不可散列的类型时,它们会引发 aTypeError而不是简单地返回。False如果您可能在运算符的任一侧得到一个不可散列的对象,那么您就不in走运了。有时您可以使用可散列元素代替(例如frozenset代替settuple代替list),有时则不能。

但是元组和列表不必散列它们的元素。


为什么要在元组上列出列表?

列表的主要优点是它们避免了一个元素的元组的语法怪癖。假设您有('foo', 'bar'),后来决定删除'bar'. 那么你有('foo'). 哎呀,看看我在那里做了什么?它实际上应该是('foo',)。很容易忘记逗号。并且in检查仍然适用于类似的字符串('foo'),因为in检查子字符串。这可以巧妙地改变程序的含义。'oo'在 中('foo'),但不在 中('foo',)

像这样的单项列表['foo']没有这个问题。[正如 user2357112 指出的那样,一个常量列表无论如何都会被编译成一个元组。]

请注意,单品套装{'a'}也没有这个问题。一个空{}是一个字典,但这不会导致in检查出现任何问题,因为它也是一个空集合。

但是可以说,在仅与一个元素进行比较时,您应该使用==而不是。in


就是为了清楚起见。现在进行微优化。早期优化是万恶之源。在实际需要之前,不要以牺牲可读性为代价进行优化。

如果不是太小,集合查找会更快,因为必须逐个检查元组的元素,这(平均)随着元组的大小而增长,而集合​​由哈希表(如字典)支持,它的开销很小。如果案例的分布不均匀,这意味着元组中元素的顺序很重要。平均而言,将更常见的情况放在元组中会使检查比相反的情况快得多。

集合必须有多小才能使集合的持续开销重要?配置文件并查看。性能可能会因许多因素而异。这不仅仅是元素的数量,而是相等检查需要多长时间,以及它们在内存中的位置等。

元组在内存和构造时间上的开销都应该比其他集合略小。但是,如果编译器可以将其加载为保存的常量值,则构造开销并不重要。(当所有元素本身在编译时都保持不变时,就会发生这种情况。您可以使用dis模块来确认这种情况正在发生。)


推荐阅读