Вопрос по python – Как сделать словарь с несколькими ключами для одного значения?

41

У меня есть вопрос о словаре, который я хочу сделать. Моя цель - иметь несколько ключей для одного значения, как показано ниже:

dictionary = {('a', 'b'): 1, ('c', 'd'): 2}
assert dictionary['a'] == 1
assert dictionary['b'] == 1

Есть идеи?

Как вы говорите, словарь ['a' a]] = 1 и словарь ['b'] = 1. GiannisIordanou
@evil_inside, ах, если это то, что ты хочешь, почему бы тебе просто не назначить 1 для обеих клавиш? senderle
stackoverflow.com/questions/2974022/…    Это может быть полезно Seraph
Возможный дубликатMultiple keys per value Eli
Вы имеете в виду, что вы хотите получить доступ к первой записи сeither 'a' или же'b'? подобноdictionary['a'] а такжеdictionary['b'] оба возвращаются1? Some programmer dude

Ваш Ответ

4   ответа
4

вы хотите использовать подход, основанный на классах, что-то похожее на ответ @ Latty в этом вопросе SO.2d-словарь с-многие-ключей-что-волевого обратный-The-же-значение.

Тем не менее, если у вас есть статический словарь, и вам нужен доступ к значениям только по нескольким ключам, тогда вы можете просто пойти по очень простому пути использования двух словарей. Один для хранения связи с псевдонимом и один для хранения ваших фактических данных:

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

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

dict[alias['a']]

Если вам нужно добавить в словарь, вы можете написать такую функцию для использования обоих словарей:

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

add('e', 'id2')
add('f', 'id3', 3)

Хотя это работает, я думаю, что в конечном итоге, если вы захотите сделать что-то подобное, написание собственной структуры данных, вероятно, будет правильным решением, хотя она может использовать аналогичную структуру.

5

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
3

что вы должны понять, дизайн интерпретатора 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

Исходя из вышеприведенного вывода, переменные a и b совместно используют одну и ту же память, c и d имеют различную память, когда я создаю новую переменную e и сохраняю значение (11), которое уже присутствует в переменной c, поэтому оно отображается в эту ячейку памяти не создает новую память, когда я изменяю значение, присутствующее в переменной e, на 21, которое уже присутствует в переменной d, так что теперь переменные d и e совместно используют одну и ту же ячейку памяти. Наконец, я изменяю значение в переменной e на 30, которое не сохраняется ни в одной другой переменной, поэтому оно создает новую память для e.

поэтому любая переменная с таким же значением разделяет память.

Not for list and dictionary objects

давайте перейдем к вашему вопросу.

когда несколько ключей имеют одно и то же значение, все они используют одну и ту же память, поэтому ожидаемая вещь уже есть в 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

Исходя из вышеприведенного вывода, ключи k1 и k2 отображаются на один и тот же адрес, что означает, что значение один хранится только один раз в памяти, которая представляет собой словарь с несколькими ключами и одним значением. Это то, что вам нужно. :П

28

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
Python's strings and numbers are immutable objects, So, if you want d['a'] and d['b'] to point to the same value that "updates" as it changes, make the value refer to a mutable object (user-defined class like above, or a dict, list, set). Then, when you modify the object at d['a'], d['b'] changes at same time because they both point to same object.
Вам не нужно использовать неизменяемый объект, просто присвойте значение, используя одну и ту же переменную (ссылка на объект), и вы получите одинаковый результат как для изменяемых, так и для неизменяемых объектов, напримерnum = 2 а не объект напрямую (num переменная и2 это объект). Вы можете проверить это с помощьюis ключевое слово, вот так:if d['a'] is d['b']: , если оба ключа указывают на один и тот же объект, то выражение будетTrue

Похожие вопросы