当前位置: 首页 > 面试题库 >

OrderedDict理解

华凌
2023-03-14
问题内容

我可以在python中扩展语法以获取其他字典的dict理解,例如collections模块中的OrderedDict或继承自我的类型dict吗?

仅仅重新绑定dict名称显然是行不通的,{key: value}理解语法仍然为您提供了理解和文字的普通旧字典。

>>> from collections import OrderedDict
>>> olddict, dict = dict, OrderedDict
>>> {i: i*i for i in range(3)}.__class__
<type 'dict'>

那么,如果可能的话,我将如何去做呢?如果它仅适用于CPython,就可以了。对于语法,我想我会O{k: v}像在上那样使用前缀尝试r'various' u'string' b'objects'

注意: 当然,我们可以使用生成器表达式来代替,但是我更感兴趣的是查看python在语法方面的可破解性。


问题答案:

没有直接的方法可以从语言中更改Python的语法。字典理解(或普通显示)总是会创建一个dict,您对此无能为力。如果使用的是CPython,它将使用特殊的字节码直接生成dict,最终会调用PyDictAPI函数和/或该API使用的相同基础函数。如果您使用的是PyPy,则这些字节码将在RPythondict对象的顶部实现,而RPython对象则在经过编译和优化的Python之上实现dict。等等。

间接的
方法可以做到,但是您不会喜欢它。如果您阅读了导入系统上的文档,您会发现是进口商搜索缓存的编译代码或调用编译器,以及编译器调用解析器,依此类推。在Python
3.3+中,该链中的几乎所有内容要么都是用纯Python编写的,要么具有替代的纯Python实现,这意味着您可以分叉代码并做自己的事情。其中包括使用构建AST的PyParsing代码解析源,或将dict理解AST节点编译为您自己的自定义字节码(而不是默认值),或者对字节码进行后处理,或者…

在许多情况下,一个导入钩子就足够了。如果没有,您可以随时编写自定义查找程序和加载程序。

如果您尚未使用Python
3.3或更高版本,我强烈建议您在使用这些东西之前先进行迁移。在较旧的版本中,它变得更困难,文档也更少,最终您将付出10倍的精力来学习每当迁移时就会过时的知识。

无论如何,如果您觉得这种方法很有趣,则可能需要看一下MacroPy。您可以从中借用一些代码,也许更重要的是,学习如何使用其中的某些功能(在文档中没有好的示例)。

或者,如果您愿意接受一些不太酷的东西,则可以使用它MacroPy来构建一个“命令理解宏”。(请注意,MacroPy当前仅在Python
2.7中工作,而不在3.x中工作。)您不能完全得到o{…},但是可以说od[{…}],这还不错。下载od.pyrealmain.pymain.py,然后运行python main.py以查看其是否正常运行。关键是此代码,该代码采用DictionaryCompAST,将其转换为GeneratorExpr键值Tuples上的等价形式,并将其包装Call到to中collections.OrderedDict

def od(tree, **kw):
    pair = ast.Tuple(elts=[tree.key, tree.value])
    gx = ast.GeneratorExp(elt=pair, generators=tree.generators)
    odict = ast.Attribute(value=ast.Name(id='collections'), 
                          attr='OrderedDict')
    call = ast.Call(func=odict, args=[gx], keywords=[])
    return call

当然,另一种替代方法是修改Python解释器。

我建议O{…}您一开始就放弃语法思想,而只是将普通的dict理解编译为dicts。好消息是,您实际上不需要更改语法(这超出了毛发……),只需更改以下任何一项即可:

  • dictcomps编译成的字节码,
  • 解释器运行这些字节码的方式,或者
  • PyDict类型的实现

坏消息是,尽管所有这些都比更改语法容易得多,但是扩展模块无法完成所有这些操作。(好吧,您可以通过执行与纯Python基本上相同的操作来做第一个……并且您可以通过将.so
/ .dll /
.dylib挂钩来修补您自己的函数来完成其中的任何一个操作,但这就是与在Python上进行黑客入侵完全相同的工作,以及在运行时进行钩子的额外工作。)

如果你想破解的CPython的来源,你想要的代码是Python/compile.cPython/ceval.cObjects/dictobject.c,和开发者指南告诉你如何找到你所需要的一切。但是您可能想考虑改用PyPy源代码,因为它主要是用Python(的子集)而不是C编写的。

附带说明一下,即使一切都在Python语言级别完成,您的尝试也不会奏效。olddict, dict = dict, OrderedDict创建一个名为绑定dict在你的模块的全局,这 阴影 中内建的名字,但不会取代它。您 可以 替换内置 函数中的
内容(嗯,Python不能保证这一点,但是有特定于实现/版本的东西-我尝试过的每个实现/版本都可以正常工作……),但是您所做的是不是这样做的方式。



 类似资料:
  • 问题内容: 我正在尝试通过 “深度” 键对OrderedDict中的OrderedDict进行排序。有什么解决方案可以对Dictionary进行排序吗? 排序的字典应如下所示: 知道如何获得它吗? 问题答案: 由于按插入顺序排序,因此您必须创建一个新的。 在您的情况下,代码如下所示: 有关更多示例,请参见http://docs.python.org/dev/library/collections.

  • 问题内容: 我指的是模块中的OrderedDict,这是一个有序的字典。 如果它具有可订购的附加功能,我意识到这通常不是必需的,但是即使如此,是否还有缺点?慢一点吗?是否缺少任何功能?我没有看到任何丢失的方法。 简而言之,为什么我 不 总是使用它而不是普通的词典? 问题答案: 是的子类,并且需要更多内存来跟踪键的添加顺序。这不是小事。该实现在幕后增加了第二个,所有键的双向链接列表(这是记住顺序的部

  • 问题内容: 我在上课时遇到了麻烦。我在Raspbian(Raspberry Pi的Debian发行版)上使用Python 2.7。我正在尝试打印两个字典,以便进行文本冒险的比较(并排)。该顺序对于准确比较至关重要。无论我尝试什么,词典都以通常的无序方式打印。 这是我在RPi上执行的操作所得到的: 显然有些不对劲,因为它正在打印函数调用并将键和值组放入嵌套列表中。 这是通过在PC上运行类似内容得到的

  • 本文向大家介绍Python OrderedDict字典排序方法详解,包括了Python OrderedDict字典排序方法详解的使用技巧和注意事项,需要的朋友参考一下 很多人认为python中的字典是无序的,因为它是按照hash来存储的,但是python中有个模块collections(英文,收集、集合),里面自带了一个子类 OrderedDict,实现了对字典对象中元素的排序。请看下面的实例:

  • 问题内容: 有序词典是非常有用的结构,但是不幸的是,它们仅在3.1和2.7版本中才是最近的版本。在旧版本中如何使用有序词典? 问题答案: 我在pip python 2.6上安装了ordereddict

  • 问题内容: 我正在尝试创建一个OrderedDict对象,但我不会立即创建它,否则所有元素都会混乱。 这是我的工作: 元素不按我分配的顺序排列 docs.python.org没有示例,我无法弄清楚订单为何变得混乱。任何帮助是极大的赞赏。 问题答案: 您的问题是,您正在构造一个将初始数据提供给的-这 不会 存储任何订单,因此订单在到达之前就丢失了。 解决方案是从有序数据类型构建-最简单的是的: 值得