[英]Which sequence type is better for a comparison and why? (Python)
我有一个条件,将一个 object 与其他几个进行比较,如下所示:
if 'a' in ('a','b','c','e'):
该序列是为此目的而创建的,在 function 的其他任何地方都不存在。 考虑到它们似乎都工作相同并且列表很短,将其分组为元组、列表或集合的优点和缺点是什么? 哪个是惯用的?
使用一套,直到你有充分的理由不这样做。 (然后使用列表。)
我会认为一组更惯用。 它更清楚地传达了含义,因为顺序无关紧要,只有成员资格。
需要明确的是,集合是一个集合,但不是“序列类型”(即使它是可迭代的),因为它在语义上是“无序的”。
为什么不使用一套?
集合只能包含可散列类型。 而且,这很重要,当您询问集合中是否存在不可散列的类型时,它们会引发TypeError
而不是简单地返回False
。 如果您可能在in
运算符的任一侧得到不可散列的 object,那么您就不走运了。 有时您可以使用可散列元素(例如frozenset
代替set
或tuple
代替list
),有时则不能。
但是元组和列表不必 hash 它们的元素。
为什么要在元组上列出列表?
列表的主要优点是它们避免了一个元素的元组的语法怪癖。 假设您有('foo', 'bar')
,后来决定删除'bar'
。 然后你有('foo')
。 哎呀,看看我在那里做了什么? 它实际上应该是('foo',)
。 很容易忘记逗号。 并且in
检查仍然适用于('foo')
这样的字符串,因为in
检查子字符串。 这可以巧妙地改变程序的含义。 'oo'
在('foo')
中,但不在('foo',)
中。
像['foo']
这样的单项列表没有这个问题。 [正如 user2357112 指出的那样,一个常量列表无论如何都会被编译成一个元组。]
请注意,像{'a'}
这样的单项集也没有这个问题。 一个空的{}
是一个 dict,但这不会导致in
检查出现任何问题,因为它也是一个空集合。
但是当只与一个元素进行比较时,可以说你应该使用==
而不是in
。
就是为了清楚起见。 现在进行微优化。 早期优化是万恶之源。 在实际需要之前,不要以牺牲可读性为代价进行优化。
如果不是太小,集合查找会更快,因为必须逐个检查元组的元素,这(平均)随着元组的大小而增长,而集合由哈希表(如字典)支持,它的开销很小。 如果案例的分布不均匀,这意味着元组中元素的顺序很重要。 平均而言,将更常见的情况放在元组中会使检查比相反的情况快得多。
集合必须有多小才能使集合的持续开销重要? 配置文件并查看。 性能可能会因许多因素而异。 这不仅仅是元素的数量,而是相等检查需要多长时间,以及它们在 memory 中的位置等。
一个元组在 memory 和构造时间上的开销都应该比另一个 collections 的开销略小。 但是,如果编译器可以将其加载为保存的常量值,则构造开销并不重要。 (当所有元素本身在编译时都保持不变时,就会发生这种情况。您可以使用dis
模块来确认这种情况正在发生。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.