Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有序理解_Python_Dictionary_Cpython_Ordereddictionary_Dictionary Comprehension - Fatal编程技术网

Python 有序理解

Python 有序理解,python,dictionary,cpython,ordereddictionary,dictionary-comprehension,Python,Dictionary,Cpython,Ordereddictionary,Dictionary Comprehension,我是否可以扩展python中的语法来理解其他dict,如集合模块中的OrderedDict或从dict继承的我自己的类型 仅仅重新绑定dict名称显然不起作用,{key:value}理解语法仍然为理解和文字提供了一个简单的旧dict >>> from collections import OrderedDict >>> olddict, dict = dict, OrderedDict >>> {i: i*i for i in range(3

我是否可以扩展python中的语法来理解其他dict,如
集合
模块中的OrderedDict或从
dict
继承的我自己的类型

仅仅重新绑定
dict
名称显然不起作用,
{key:value}
理解语法仍然为理解和文字提供了一个简单的旧dict

>>> from collections import OrderedDict
>>> olddict, dict = dict, OrderedDict
>>> {i: i*i for i in range(3)}.__class__
<type 'dict'>
>>从集合导入订单数据
>>>olddict,dict=dict,OrderedDict
>>>{i:i*i表示范围(3)}.\u类__
那么,如果可能的话,我该怎么做呢?如果它只在CPython中起作用就可以了。对于语法,我想我会尝试使用
O{k:v}
前缀,就像我们在
r'各种'u'字符串'b'对象'
上一样


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

对不起,不可能。Dict文本和Dict理解映射到内置的Dict类型,其方式是在C级硬编码的。这是不可推翻的

不过,您可以将其用作备选方案:

OrderedDict((i, i * i) for i in range(3))

附录:从Python 3.6开始,所有Python字典都已订购,它甚至是语言规范的一部分。如果您使用的是那些版本的Python,则无需使用OrderedDict:dict理解将只起作用(TM)。

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


有一种间接的方法,但你不会喜欢的。如果您继续阅读文档,您将看到是导入程序搜索缓存的编译代码或调用编译器,编译器调用解析器,等等。在Python3.3+中,这条链中的几乎所有内容要么是用纯Python编写的,要么有另一个纯Python实现,这意味着您可以分叉代码并做自己的事情。其中包括使用您自己的PyParsing代码解析源代码以构建AST,或将dict CONTRUSION AST节点编译为您自己的自定义字节码而不是默认字节码,或对字节码进行后处理,或

在许多情况下,一个标准就足够了;如果没有,您可以编写一个定制的查找器和加载器

如果您还没有使用Python3.3或更高版本,我强烈建议您在使用这些东西之前进行迁移。在较旧的版本中,这更难,文档也更少,并且最终您将投入10倍的精力来学习在迁移时将过时的东西

无论如何,如果您对这种方法感兴趣,您可能想看看。您可以从中借用一些代码,也许更重要的是,了解其中一些功能(文档中没有好的示例)是如何使用的

或者,如果你愿意接受一些不那么酷的东西,你可以使用
MacroPy
来构建一个“odict理解宏”,并使用它。(请注意,MacroPy目前仅在Python2.7中工作,而不是在3.x中工作。)您无法获得
o{…}
,但您可以获得,比如,
od[{…}]
,这并不太糟糕。下载、和,然后运行
python main.py
查看它的工作情况。关键是这段代码,它接受一个
字典comp
AST,将其转换为键值
元组
上的等效
生成器expr
,并将其包装在
调用
集合中。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理解编译成odicts即可。好消息是,您实际上不需要更改语法(这超出了毛茸茸的…),只需更改以下任何一项:

  • dictcomps编译到的字节码
  • 解释器运行这些字节码的方式,或者
  • PyDict
    类型的实现
坏消息是,虽然所有这些都比更改语法容易得多,但没有一个可以通过扩展模块完成。(好的,你可以做第一件事,基本上和你在纯Python上做的一样……你也可以做任何一件事,把.so/.dll/.dylib挂接到你自己的函数中,但这和在Python上做黑客加上在运行时挂接的额外工作完全一样。)

如果您想破解,所需的代码位于
Python/compile.c
Python/ceval.c
Objects/dictobject.c
中,并告诉您如何找到所需的一切。但是你可能想考虑黑客攻击,因为它主要是写在(Python的一个子集而不是C.

)中。

顺便说一句,即使一切都是在Python语言级别完成的,您的尝试也不会成功
olddict,dict=dict,OrderedDict
在模块的全局中创建名为
dict
的绑定,该绑定将名称隐藏在内置项中,但不会替换它。您可以替换内置的东西(好吧,Python不能保证这一点,但是对于我尝试过的每个实现/版本,都有一些特定于实现/版本的东西……),但是您所做的不是这样做的。

稍微修改@Max Noel的响应,您可以使用列表理解而不是生成器以有序方式创建OrderedICT(当然,使用dict理解是不可能的)

“我可以扩展语法吗”,你的意思是定制CPython或PyPy之类的东西,还是说fr
>>> OrderedDict([(i, i * i) for i in range(5)])
OrderedDict([(0, 0), 
             (1, 1), 
             (2, 4), 
             (3, 9), 
             (4, 16)])