如何将具有多个键的字典创建为一个值?

Gia*_*nou 49 python dictionary

我有一个关于我想要的字典的问题.我的目标是为单个值设置多个键,如下所示:

dictionary = {('a', 'b'): 1, ('c', 'd'): 2}
assert dictionary['a'] == 1
assert dictionary['b'] == 1
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

fan*_*lix 29

我想你的意思是:

class Value:
    def __init__(self, v=None):
        self.v = v

v1 = Value(1)
v2 = Value(2)

d = {'a': v1, 'b': v1, 'c': v2, 'd': v2}
d['a'].v += 1

d['b'].v == 2 # True
Run Code Online (Sandbox Code Playgroud)
  • Python的字符串和数字是不可变对象,
  • 所以,如果你想d['a']d['b']指向相同的值是"更新",因为它的变化,使值指的是可变对象(用户定义的类像上面,或者dict,list,set).
  • 然后,当您修改对象时d['a'],d['b']会同时更改,因为它们都指向同一个对象.


sag*_*e88 7

如果您要经常添加到该字典中,则需要采用基于类的方法,类似于@Latty在此SO问题中的答案2d-dictionary-with-many-keys-that-return-the -相同值

但是,如果您有一个静态字典,并且只需要通过多个键访问值,则可以走使用两个字典的非常简单的路线。一种用于存储别名密钥关联,另一种用于存储实际数据:

alias = {
    'a': 'id1',
    'b': 'id1',
    'c': 'id2',
    'd': 'id2'
}

dictionary = {
    'id1': 1,
    'id2': 2
}

dictionary[alias['a']]
Run Code Online (Sandbox Code Playgroud)

如果您需要添加到字典中,则可以编写使用两个字典的函数,如下所示:

def add(key, id, value=None)
    if id in dictionary:
        if key in alias:
            # Do nothing
            pass
        else:
            alias[key] = id
    else:
        dictionary[id] = value
        alias[key] = id

add('e', 'id2')
add('f', 'id3', 3)
Run Code Online (Sandbox Code Playgroud)

虽然这行得通,但我认为最终您想做的事情就是编写自己的数据结构,尽管它可以使用类似的结构,但这可能是您要走的路。


kat*_*aja 7

很简单。首先要了解Python解释器的设计。如果任何两个或多个变量具有仅映射到该值的相同值,则基本上不会为所有变量分配内存。

让我们来看代码示例,

In [6]: a = 10

In [7]: id(a)
Out[7]: 10914656

In [8]: b = 10

In [9]: id(b)
Out[9]: 10914656

In [10]: c = 11

In [11]: id(c)
Out[11]: 10914688

In [12]: d = 21

In [13]: id(d)
Out[13]: 10915008

In [14]: e = 11

In [15]: id(e)
Out[15]: 10914688

In [16]: e = 21

In [17]: id(e)
Out[17]: 10915008

In [18]: e is d
Out[18]: True
In [19]: e = 30

In [20]: id(e)
Out[20]: 10915296
Run Code Online (Sandbox Code Playgroud)

从上面的输出中,变量a和b共享相同的内存,当我创建新变量e并存储变量c中已经存在的值(11)时,c和d具有不同的内存,因此将其映射到该内存位置,并且当我将变量e中已经存在的值更改为21时,不会创建新的内存,因此现在变量d和e共享相同的内存位置。最后,我将变量e中的值更改为30,该值未存储在任何其他变量中,因此它为e创建了新的内存。

因此,具有相同值的任何变量都将共享内存。

不适用于列表和字典对象

让我们提出您的问题。

当多个键具有相同的值时,它们都共享相同的内存,因此您期望的东西已经存在于python中。

您可以像这样简单地使用它

In [49]: dictionary = {
    ...:     'k1':1,
    ...:     'k2':1,
    ...:     'k3':2,
    ...:     'k4':2}
    ...:     
    ...:     

In [50]: id(dictionary['k1'])
Out[50]: 10914368

In [51]: id(dictionary['k2'])
Out[51]: 10914368

In [52]: id(dictionary['k3'])
Out[52]: 10914400

In [53]: id(dictionary['k4'])
Out[53]: 10914400
Run Code Online (Sandbox Code Playgroud)

从上面的输出中,键k1和k2映射到相同的地址,这意味着值1仅在内存中存储一​​次,该内存是多键单值字典,这就是您想要的东西。:P

  • 我相信这只是因为 Python 存储了较小数字的对象,因此不必每次都重新创建它们。如果您要存储更复杂的数据,例如更大的数字或字符串等,则情况并非如此。 (2认同)

小智 6

如果使用,您的示例将创建多个键:值对fromkeys.如果您不想这样,可以使用一个密钥并为密钥创建别名.例如,如果您使用寄存器映射,则您的密钥可以是寄存器地址,而别名可以是寄存器名称.这样,您就可以在正确的寄存器上执行读/写操作.

>>> mydict = {}
>>> mydict[(1,2)] = [30, 20]
>>> alias1 = (1,2)
>>> print mydict[alias1]
[30, 20]
>>> mydict[(1,3)] = [30, 30]
>>> print mydict
{(1, 2): [30, 20], (1, 3): [30, 30]}
>>> alias1 in mydict
True
Run Code Online (Sandbox Code Playgroud)