现在,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']
这将保留第一次出现时的顺序,并消除所有重复项。
我想知道社区对此用例和订单保留功能的总体看法。
通读Python的Zen,我感到矛盾。该方法很简单,但是依赖于隐式排序。
请让我知道您的想法。谢谢。
答案 0 :(得分:6)
这在Python 3.7上效果很好!..但是Python 3.7并不是唯一的Python版本。依赖dict顺序保存在相当长的一段时间内将是一种危险的习惯,因为如果您的代码曾经在3.6之前的Python版本上运行,它将停止保持命令,而完全是静默的。
例如,依靠dataclasses
或contextvars
并不是那么危险,因为如果您尝试在没有Python的Python上运行依赖于dataclasses
的代码, dataclasses
,您将获得一个清晰的ImportError
。失去顺序的词典看起来不一样。
您可能不知道它已停止维护订单。您可能不记得自己依赖于字典顺序。您可能会忘记记录文档或告诉任何人您依赖它,或者您可能是可怜的编码器,他们继承了别人依赖于dict顺序的代码,而没有记录Python 3.7+要求。您可能不知道自己忘记在一台特定计算机上更新Python,或者不小心退出了Anaconda或其他任何东西,而您正在使用的Python 3系统仍在使用3.4。
最终假设命令是安全的。就目前而言,尤其是现在 ,在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))
答案 1 :(得分:5)
核心Python开发人员here审查了将Python 3.7字典用作保留顺序重复数据删除的方法。真的没有比这更好的推荐了。
有什么理由不应该使用这种方法吗?
否。
有没有更好的方法来解决这个问题?
否。
此方法是Pythonic吗?
是的
该方法很简单,但是依赖于隐式排序。
您的问题被标记为python-3.7。保证了字典保留插入顺序,因此这里没有隐式顺序。