简体   繁体   English

将命令字典设为默认?

[英]Make ordered dict default?

Is it possible to make default dict literal to create ordered dicts not unordered ones? 是否可以使用默认字典文字来创建有序字典而不是无序字典?

I would like to type complex nested configs like: 我想输入复杂的嵌套配置,例如:

config = {
   'train': {
       'speed': 0.001,
       'initial_values': [1, 2, 3]
   },
   'model': {
...
   }
}

and an idea to write a mess of brackets 和写一堆括号的想法

config = OrderedDict([(
    'train', OrderedDict([(
       'speed', 0.001), (
       'initial_values', [1, 2, 3])]),(
    'model', OrderedDict([(
...

is absolutely unaplicable. 绝对不适用。

Please no phylosophy about why my wish is bad. 请不要为我的愿望为什么不好而生疏。


Ok, currently I would write somethong like: 好吧,目前我会写一些东西:

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(
    ...
     )
)

No, you can't alter Python syntax, not without altering the CPython source code and recompiling, but then it would not be Python any more. 不,您不能更改Python语法,不能不更改CPython源代码并重新编译,但是那样就不再是Python。

The best you can do is to upgrade to Python 3.6 or newer , where dictionaries retain insertion order by default . 最好的办法是升级到Python 3.6或更高版本默认情况下字典将保留插入顺序 If you must have the full OrderedDict feature set (reordering, reversing, dict views with ordering), then convert those regular dictionaries to OrderedDict objects after the fact: 如果必须具有完整的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

and then stick to using {...} notation with a config = to_ordered_dict(config) line at the end. 然后坚持使用{...}表示法,最后使用config = to_ordered_dict(config)行。

There's no philosophical reason why you shouldn't get to do this, but you may not do it by altering fundamental Python syntax. 出于哲学上的原因,您不应该这样做,但是您可能无法通过更改基本的Python语法来做到这一点。 As mentioned elsewhere Python dictionaries can retain order after 3.6, but if you must use OrderedDict 如其他地方所述,Python字典可以在3.6之后保留顺序,但是如果必须使用OrderedDict

d = OrderedDict

config = d([(...)])

You can do the same with methods like .update 您可以使用.update方法执行相同.update

Although this doesn't directly answer to your question the way you stated it, I guess you really want to have ability to process some configs. 尽管这并不能按照您所说的方式直接回答您的问题,但我想您确实希望能够处理一些配置。 I usually prefer saving configs not in python files, but in some structured data format. 我通常更喜欢将配置保存在python文件中,而不是以某种结构化数据格式保存。 So if you can admit usage of json you could do the following. 因此,如果您可以使用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))

This should work even in python 2.7. 即使在python 2.7中也应如此。

And if you have a dedicated file for config then you can do something like 如果您有专用的配置文件,则可以执行以下操作

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM