将命令字典设为默认?

时间:2018-11-24 14:23:46

标签: python dictionary literals ordereddictionary

是否可以使用默认的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(
    ...
     )
)

3 个答案:

答案 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))