gpt4 book ai didi

python-3.x - 为什么 python 字典对于 python3.7 不可逆?

转载 作者:行者123 更新时间:2023-12-03 00:38:18 27 4
gpt4 key购买 nike

从3.7开始,标准Python字典保证保持插入顺序。 (*)

d = {'b': 1, 'a': 2}
for k in d:
print(k)
# Prints always 'b' before 'a'.

换句话说,字典键按照严格的顺序保存。原则上,这将允许 key 是可逆的。但是,以下方法均无效:

# TypeError: 'dict' object is not reversible
for k in reversed(d):
print(k)

# TypeError: 'dict_keys' object is not reversible
for k in reversed(d.keys()):
print(k)

问题:此行为背后的原因是什么?为什么命令没有变得可逆?将来有计划改变这种行为吗?

解决方法当然有效:

for k in reversed(list(d.keys())): 
print(k)

(*) 事实上,Python 3.6 的典型安装已经出现这种情况,如 this post 中所述。 .

<小时/>

更新:从 python 3.8 开始字典实际上是可逆的。接受的答案是指 Guido 和其他核心开发人员之间的讨论导致了这一决定。简而言之,他们根据实现工作和用户的实际 yield 来衡量语言一致性。

最佳答案

来自docs :

reversed(seq)

Return a reverse iterator. seq must be an object which has a __reversed__() method or supports the sequence protocol (the __len__() method and the __getitem__() method with integer arguments starting at 0).

dict 对象未实现 __reversed__。它确实实现了后两种方法。但是,__getitem__ 将键作为参数,而不是整数(从 0 开始)。

至于为什么,这个已经有人建议和讨论过here .

编辑:

这些引言来自Python-Dev mailing list (线程“为 dict 添加 __reversed__ 方法”,于 18 年 5 月 25 日开始),我将从“概念”参数开始,第一个来自 Antoine Pitrou:

It's worth nothing that OrderedDict already supports reversed(). The argument could go both ways:

  1. dict is similar to OrderedDict nowadays, so it should support reversed() too;

  2. you can use OrderedDict to signal explicitly that you care about ordering; no need to add anything to dict.

My thought is that guaranteed insertion order for regular dicts is brand new, so it will take a while for the notion settle in and become part of everyday thinking about dicts. Once that happens, it is probably inevitable that use cases will emerge and that __reversed__ will get added at some point. The implementation seems straightforward and it isn't much of a conceptual leap to expect that a finite ordered collection would be reversible.

接下来是 Raymond Hettinger 的回复:

Given that dicts now track insertion order, it seems reasonable to want to know the most recent insertions (i.e. looping over the most recently added tasks in a task dict). Other possible use cases will likely correspond to how we use the Unix tail command.

If those use cases arise, it would be nice for __reversed__ to already be supported so that people won't be tempted to implement an ugly workaround using popitem() calls followed by reinsertions.

邮件列表中表达的主要担忧,这至少在某些实现中会增加太多的膨胀或降低内存效率(必须使用双链表而不是单链表),这里是Inada Naoki 在 Python bug 跟踪器 ( issue 33462 ) 中的引用:

"Have an order" doesn't mean "reversible". For example, single linked list is ordered, but not reversible.

While CPython implementation can provide efficient __reverse__, adding __reverse__ means all Python implementation is expected to provide it. For example, some Python implementation may be able to implement dict with hashmap + single linked list. If __reverse__ is added, it's not possible anymore.

返回邮件列表,这是最后两条消息(均发布于 08.06.2018)。首先来自 Michael Selik:

Am I correct in saying that the consensus is +1 for inclusion in v3.8?

The last point in the thread was INADA Naoki researching various implementations and deciding that it's OK to include this feature in 3.8. As I understand it, Guido was in agreement with INADA's advice to wait for MicroPython's implementation of v3.7. Since INADA has changed minds, I'm guessing it's all in favor?

以 Guido van Rossum 的消息结束:

That sounds right to me. We will then have had two versions where this was the case:

  • 3.6 where order preserving was implemented in CPython but in the language spec

  • 3.7 where it was also added to the language spec

正如其他答案和评论中所述,自 3.8 版(2018 年 10 月 14 日)起,dict 和 dictview 均支持 reversed()

关于python-3.x - 为什么 python 字典对于 python3.7 不可逆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58413076/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com