使用有序字典作为有序集
Using ordered dictionary as ordered set
既然 Python 3.7 生成了保留顺序的指令 officially part of the language spec 而不是实现细节,我一直在努力思考如何最好地使用它 属性。今天,我发现我需要一个顺序保留集,并且认为字典可以解决问题。
假设我们有一个可哈希元素列表。我们想要一个唯一条目的列表,并且我们希望根据第一次出现来保持这些条目的顺序。一个简单的字典构造函数应该可以解决问题:
ls = "Beautiful is better than ugly. Explicit..."
uniques = list({s:0 for s in ls})
>>> ['B', 'e', 'a', 'u', 't', 'i', 'f', 'l', ' ', 's', 'b', 'r', 'h', 'n', 'g', 'y', '.', 'E', 'x', 'p', 'c']
这将保留首次出现的顺序并删除所有重复项。
我想知道社区对这个用例的看法以及一般的顺序保留功能。
- 有什么理由不应该使用这种方法吗?
- 有没有更好的方法来解决这个问题?
- 这个方法Pythonic吗?
通读Python的禅宗,我很矛盾。该方法很简单,但依赖于隐式排序。
请告诉我您的想法。谢谢。
这种使用 Python 3.7 字典作为保序重复数据删除的方法已经过核心 Python 开发人员 here 的审核。没有比这更好的推荐了。
Is there any reason this method shouldn't be used?
没有
Are there better ways to solve this problem?
没有
Is this method Pythonic?
是的。
The method is simple but relies on implicit ordering.
您的问题被标记为 python-3.7。保留插入顺序的字典是有保证的,所以这里没有隐式排序。
这在 Python 3.7 上运行良好!...但是 Python 3.7 并不是唯一的 Python 版本。在很长一段时间内,依赖字典顺序保存将成为一个危险的习惯,因为如果你的代码 运行s 在 3.6 之前的 Python 版本上,它将停止维护顺序,完全静默。
例如,依赖 dataclasses
或 contextvars
并不危险,因为如果您尝试 运行 依赖 dataclasses
的代码Python 没有 dataclasses
,你得到一个大而清晰的 ImportError
。 Dicts 失去他们的顺序没有同样明显。
您可能不知道它已停止维持秩序。你可能不记得你依赖于 dict 命令。您可能会忘记记录或告诉任何人您依赖它,或者您可能是继承了其他人依赖 dict 顺序的代码而没有记录 Python 3.7+ 要求的可怜的编码员。您可能不知道您忘记在一台特定机器上更新 Python,或者您不小心退出了 Anaconda 或其他任何东西,而您在系统 Python 3 上仍在使用 3.4.
最终采用 dict 顺序是安全的。目前,尤其是现在,在3.7发布几天后,最好使用OrderedDict
,或者添加版本检查:
import collections
import sys
_make_ordered_mapping = (dict.fromkeys if sys.version_info >= (3, 7)
else collections.OrderedDict.fromkeys)
def ordered_dedup(items):
return list(_make_ordered_mapping(items))
既然 Python 3.7 生成了保留顺序的指令 officially part of the language spec 而不是实现细节,我一直在努力思考如何最好地使用它 属性。今天,我发现我需要一个顺序保留集,并且认为字典可以解决问题。
假设我们有一个可哈希元素列表。我们想要一个唯一条目的列表,并且我们希望根据第一次出现来保持这些条目的顺序。一个简单的字典构造函数应该可以解决问题:
ls = "Beautiful is better than ugly. Explicit..."
uniques = list({s:0 for s in ls})
>>> ['B', 'e', 'a', 'u', 't', 'i', 'f', 'l', ' ', 's', 'b', 'r', 'h', 'n', 'g', 'y', '.', 'E', 'x', 'p', 'c']
这将保留首次出现的顺序并删除所有重复项。
我想知道社区对这个用例的看法以及一般的顺序保留功能。
- 有什么理由不应该使用这种方法吗?
- 有没有更好的方法来解决这个问题?
- 这个方法Pythonic吗?
通读Python的禅宗,我很矛盾。该方法很简单,但依赖于隐式排序。
请告诉我您的想法。谢谢。
这种使用 Python 3.7 字典作为保序重复数据删除的方法已经过核心 Python 开发人员 here 的审核。没有比这更好的推荐了。
Is there any reason this method shouldn't be used?
没有
Are there better ways to solve this problem?
没有
Is this method Pythonic?
是的。
The method is simple but relies on implicit ordering.
您的问题被标记为 python-3.7。保留插入顺序的字典是有保证的,所以这里没有隐式排序。
这在 Python 3.7 上运行良好!...但是 Python 3.7 并不是唯一的 Python 版本。在很长一段时间内,依赖字典顺序保存将成为一个危险的习惯,因为如果你的代码 运行s 在 3.6 之前的 Python 版本上,它将停止维护顺序,完全静默。
例如,依赖 dataclasses
或 contextvars
并不危险,因为如果您尝试 运行 依赖 dataclasses
的代码Python 没有 dataclasses
,你得到一个大而清晰的 ImportError
。 Dicts 失去他们的顺序没有同样明显。
您可能不知道它已停止维持秩序。你可能不记得你依赖于 dict 命令。您可能会忘记记录或告诉任何人您依赖它,或者您可能是继承了其他人依赖 dict 顺序的代码而没有记录 Python 3.7+ 要求的可怜的编码员。您可能不知道您忘记在一台特定机器上更新 Python,或者您不小心退出了 Anaconda 或其他任何东西,而您在系统 Python 3 上仍在使用 3.4.
最终采用 dict 顺序是安全的。目前,尤其是现在,在3.7发布几天后,最好使用OrderedDict
,或者添加版本检查:
import collections
import sys
_make_ordered_mapping = (dict.fromkeys if sys.version_info >= (3, 7)
else collections.OrderedDict.fromkeys)
def ordered_dedup(items):
return list(_make_ordered_mapping(items))