是否可以使用默认的dict文字来创建有序dict而不是无序dict?
我想输入复杂的嵌套配置,例如:
config = {
'train': {
'speed': 0.001,
'initial_values': [1, 2, 3]
},
'model': {
...
}
}
和写一堆括号的想法
config = OrderedDict([(
'train', OrderedDict([(
'speed', 0.001), (
'initial_values', [1, 2, 3])]),(
'model', OrderedDict([(
...
绝对不适用。
请不要为我的愿望为什么不好而生。
好,目前我会写一些东西:
def od(*args):
return OrderedDict([(args[i], args[i+1]) for i in range(0, len(args), 2)])
config = od(
'train', od(
'speed', 0.001,
'initial_values', [1, 2, 3]
),
'model', od(
...
)
)
答案 0 :(得分:5)
不,您不能更改Python语法,不能不更改CPython源代码并重新编译,但是那样就不再是Python。
最好的办法是升级到Python 3.6或更高版本,其中的字典为retain insertion order by default。如果您必须具有完整的OrderedDict
功能集(重新排序,反转,带排序的dict视图),请在事实之后将这些常规词典转换为OrderedDict
对象:
from collections import OrderedDict
from functools import singledispatch
@singledispatch
def to_ordered_dict(d):
"""Convert dictionaries to OrderedDict objects, recursively
Assumes you want to use current dictionary iteration order; in Python 3.7
and newer that's the same as insertion order (or earlier if on PyPy, or
when using CPython, 3.6 and newer).
"""
return d
@to_ordered_dict.register(dict)
def _dict(d):
return OrderedDict(
(to_ordered_dict(k), to_ordered_dict(v))
for k, v in d.items()
)
@to_ordered_dict.register(list)
@to_ordered_dict.register(tuple)
def _sequence(s):
return type(s)(map(to_ordered_dict, s))
# add additional type registrations for other compound or container types
,然后坚持使用{...}
表示法,并在末尾有config = to_ordered_dict(config)
行。
答案 1 :(得分:2)
没有哲学上的原因为什么您不应该这样做,但是您可能不能通过更改基本的Python语法来做到这一点。如其他地方所述,Python字典可以保留3.6之后的顺序,但是如果您必须使用OrderedDict
d = OrderedDict
config = d([(...)])
您可以使用.update
答案 2 :(得分:1)
尽管这并不能像您所说的那样直接回答您的问题,但我想您确实希望能够处理一些配置。我通常更喜欢将配置保存在python文件中,而不是以某种结构化数据格式保存。因此,如果您可以接受json的使用,则可以执行以下操作。
from collections import OrderedDict
import json
result = json.loads(
'''
{
"train": {
"speed": 0.001,
"initial_values": [1, 2, 3]
},
"model": {
"name": "model_name",
"wheight" : 128000
}
}
''',
object_pairs_hook=lambda pairs: OrderedDict(pairs))
即使在python 2.7中也应如此。
如果您有用于配置的专用文件,则可以执行类似的操作
from collections import OrderedDict
import json
with open('settings.conf', 'r') as f:
settings_str = f.read()
settings = json.loads(settings_str, object_pairs_hook=lambda pairs: OrderedDict(pairs))