带点的字典键不适用于 update()?

Dictionary keys with a dot does not work with update()?

我想使用包含点的键的字典 parDict 并发现 update 函数不解释带点的键,尽管字典工作正常。 点符号是由于参数集的面向对象。

下面的例子说明了“不一致”。

parDict = {}
parDict['a'] = 1
parDict['b'] = 2
parDict['group1.b'] = 3 

parDict 的多个更新可以在一条命令中完成,这对我来说很重要

parDict.update(a=4, b=4)

但无法识别以下更新

parDict.update(group1.b=4)

我得到:“语法错误:表达式不能包含赋值,...”

然而,

parDict['group1.b'] = 4

工作正常。

有没有一种方法可以解决这种“不一致”问题,即使对于名称中带有点的键也可以使用 update()

或许了解为什么 update() 在这里不起作用的更广泛背景会很有趣。

我可以想到以下解决方法。通过这种方式,您可以使用单个命令持续更新 parDict

parDict = {}
parDict['a'] = 1
parDict['b'] = 2
parDict['group1.b'] = 3
parDict.update(a=4, b=4)
print(parDict)
parDict.update({"a":5, "group1.b":7})
print(parDict)

输出:

{'a': 4, 'b': 4, 'group1.b': 3}
{'a': 5, 'b': 4, 'group1.b': 7}

先来看看update是怎么调用的。根据 Python docs(强调我的),

update() accepts either another dictionary object or an iterable of key/value pairs (as tuples or other iterables of length two). If keyword arguments are specified, the dictionary is then updated with those key/value pairs: d.update(red=1, blue=2).

但是如何定义关键字参数呢?根据Python docs(强调我的),

keyword argument: an argument preceded by an identifier (e.g. name=) in a function call or passed as a value in a dictionary preceded by **.

但什么是标识符?根据 Python docs,

The valid characters for identifiers are the same as in Python 2.x: the uppercase and lowercase letters A through Z, the underscore _ and, except for the first character, the digits 0 through 9.

哦,好的。因此,您可以使用 namea 等标识符,但不能使用 group1.b 等标识符,因为其中有一个点。

回到update方法,如果你有一个不是标识符的字典键,你可以使用字典来更新它:

parDict.update({"group1.b": 4})

I am glad for the input I have got on my questions around parDict, although my original neglect of the difference between "keys" and "identifiers" is very basic. The purpose I have in mind is to simplify command-line interaction with an object-oriented parameter structure. It is a problem of some generality and perhaps here are better solutions than what I suggest below?

Using update() with tuples is attractive, more readable and avoid using a few signs as pointed out at the link @wjandrea posted. But to use it this way we need to introduce another dictionary, i.e. we have parDict with short unique parameter names and use identifiers and corresponding values, and then introduce parLocation that is a dictionary that relates the short names parameter names to the location object-oriented string.

The solution

parDict = {}
parDict['a'] = 1
parDict['b'] = 2
parDict['group1_b'] = 3

parLocation = {}
parLocation['a'] = 'a'
parLocation['b'] = 'b'
parLocation['group1_b'] = 'group1.b'

For command line-interaction I can now write

parDict.update(b=4, group1_b=4)

And for the internal processing where parameter values are brought to the object-oriented system I write something like

for key in parDict.keys(): set(parLocation[key], parDict[key])

where set() is some function that take as arguments parameter "location" and "value".

Since the problem has some generality I though here might be some other better or more direct approach?