python - 哪种序列类型更适合比较,为什么?(Python)
问题描述
我有一个条件将一个对象与其他几个对象进行比较,如下所示:
if 'a' in ('a','b','c','e'):
该序列是为此目的而创建的,并且在函数的其他任何地方都不存在。考虑到它们似乎都工作相同并且列表很短,将其分组为元组、列表或集合的优点和缺点是什么?哪个是惯用的?
解决方案
使用一套,直到你有充分的理由不这样做。(然后使用列表。)
我会认为一组更惯用。它更清楚地传达了含义,因为顺序无关紧要,只有成员资格。
需要明确的是,集合是一个集合,但不是“序列类型”(即使它是可迭代的),因为它在语义上是“无序的”。
为什么不使用一套?
集合只能包含可散列类型。而且,这很重要,当您询问集合中是否有不可散列的类型时,它们会引发 aTypeError
而不是简单地返回。False
如果您可能在运算符的任一侧得到一个不可散列的对象,那么您就不in
走运了。有时您可以使用可散列元素代替(例如frozenset
代替set
或tuple
代替list
),有时则不能。
但是元组和列表不必散列它们的元素。
为什么要在元组上列出列表?
列表的主要优点是它们避免了一个元素的元组的语法怪癖。假设您有('foo', 'bar')
,后来决定删除'bar'
. 那么你有('foo')
. 哎呀,看看我在那里做了什么?它实际上应该是('foo',)
。很容易忘记逗号。并且in
检查仍然适用于类似的字符串('foo')
,因为in
检查子字符串。这可以巧妙地改变程序的含义。'oo'
在 中('foo')
,但不在 中('foo',)
。
像这样的单项列表['foo']
没有这个问题。[正如 user2357112 指出的那样,一个常量列表无论如何都会被编译成一个元组。]
请注意,单品套装{'a'}
也没有这个问题。一个空{}
是一个字典,但这不会导致in
检查出现任何问题,因为它也是一个空集合。
但是可以说,在仅与一个元素进行比较时,您应该使用==
而不是。in
就是为了清楚起见。现在进行微优化。早期优化是万恶之源。在实际需要之前,不要以牺牲可读性为代价进行优化。
如果不是太小,集合查找会更快,因为必须逐个检查元组的元素,这(平均)随着元组的大小而增长,而集合由哈希表(如字典)支持,它的开销很小。如果案例的分布不均匀,这意味着元组中元素的顺序很重要。平均而言,将更常见的情况放在元组中会使检查比相反的情况快得多。
集合必须有多小才能使集合的持续开销重要?配置文件并查看。性能可能会因许多因素而异。这不仅仅是元素的数量,而是相等检查需要多长时间,以及它们在内存中的位置等。
元组在内存和构造时间上的开销都应该比其他集合略小。但是,如果编译器可以将其加载为保存的常量值,则构造开销并不重要。(当所有元素本身在编译时都保持不变时,就会发生这种情况。您可以使用dis
模块来确认这种情况正在发生。)
推荐阅读
- python - python selenium 元素已定位但不可点击 - 超时异常
- oauth - 使用客户端、服务器、数据库和 Auth0 的一次性密码身份验证流程
- android - 如何在android中使用openCV拍照?
- angular - Array.push 使所有对象都相同
- excel - 当值不为零时,循环通过列并将值复制到其他工作表vba excel
- android - BubbleWrap CLI 显示错误 The given android-sdk is not correct when bubblewrap build
- javascript - 如何在mongodb中将集合A中的字符串与集合B匹配
- bash - 从文本文件中提取属性值
- google-cloud-storage - 我们可以使用单个 Google Cloud Dataflow 将来自多个 Pubsub(源)的数据写入多个 GCS(接收器)吗?
- wordpress - woocommerce 中的四舍五入价格