Можно ли назначить одно и то же значение нескольким ключам в объекте dict одновременно? - PullRequest
36 голосов
/ 04 июня 2010

В Python мне нужен объект словаря, который выглядит следующим образом:

{'a': 10, 'b': 20, 'c': 10, 'd': 10, 'e': 20}

Я смог добиться этого успешно, объединив функции dict.update() и dict.fromkeys() следующим образом:

myDict = {}
myDict.update(dict.fromkeys(['a', 'b', 'c'], 10))
myDict.update(dict.fromkeys(['b', 'e'], 20))

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

myDict = {}
myDict['a', 'c', 'd'] = 10
myDict['b', 'e'] = 20

Это, однако, дает мне:

myDict = {('a', 'c', 'd'): 10, ('b', 'e'): 20}

Есть ли способ, которым я могу упростить мой первый пример (используя dict.update() и dict.fromkeys()) дальше, и получить объект dict, который я ищу?

Или, в качестве альтернативы, если у меня есть диктат с кортежами, как во втором примере, есть ли для меня простой способ сделать поиск, например myDict['c'] или myDict.get('c'), и получить значение 10?

Ответы [ 6 ]

42 голосов
/ 04 июня 2010

Я бы сказал, что у вас есть очень просто, вы могли бы немного улучшить его, чтобы оно было:

my_dict = dict.fromkeys(['a', 'b', 'c'], 10)
my_dict.update(dict.fromkeys(['b', 'e'], 20))

Если ваши ключи кортежи, вы можете сделать:

>>> my_dict = {('a', 'c', 'd'): 10, ('b', 'e'): 20}
>>> next(v for k, v in my_dict.items() if 'c' in k)      # use .iteritems() python-2.x
10

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

12 голосов
/ 29 августа 2017

Похоже на @SilentGhost, но я предпочитаю более декларативный синтаксис:

myDict = {
  **dict.fromkeys(['a', 'b', 'c'], 10), 
  **dict.fromkeys(['b', 'e'], 20)
}
7 голосов
/ 04 июня 2010

Ваш первый пример можно упростить с помощью цикла:

myDict = {}
for key in ['a', 'c', 'd']:
    myDict[key] = 10
for key in ['b', 'e']:
    myDict[key] = 20

Нет специального синтаксиса или хитрости, и я не могу придумать ничего, что было бы легче понять.

Что касается вашего второго вопроса, не существует простого и эффективного способа выполнить поиск, как в вашем втором примере. Я могу думать только о переборе ключей (кортежей) и проверке, есть ли ключ в каком-либо из них, а это не то, что вы ищете. Придерживайтесь простой диктовки с нужными клавишами.

В общем, если вы стремитесь к коду, который может быть понят новичками, придерживайтесь основ, таких как условия и циклы for / while.

6 голосов
/ 04 июня 2010

Почему бы не наследовать от dict?

class LazyDict(dict):
    def keylist(self, keys, value):
        for key in keys:
            self[key] = value

>>> d = LazyDict()
>>> d.keylist(('a', 'b', 'c'), 10)
>>> d
{'a': 10, 'c': 10, 'b': 10}

но я предпочитаю циклическое решение

1 голос
/ 26 апреля 2018

Метод:

def multi_key_dict_get(d, k):
    for keys, v in d.items():
        if k in keys:
            return v
    return None

Использование:

my_dict = {
   ('a', 'b', 'c'): 10,
   ('p', 'q', 'r'): 50
}

value = multi_key_dict_get(my_dict, 'a')
0 голосов
/ 28 июля 2018

Есть один способ, который приходит на ум. По-прежнему имеет ограничение только на одно и то же содержимое.

Значение одного ключа не может изменить другое.

key_map = {   
    'KEY_UP':move_up,
    'w':'KEY_UP',
}

для ввода key_map:

# loop over the `dict`

if key_map[key] in key_map:
    # one key is the value of the other

    target_key = key_map[key]
    key_map[key] = key_map[target_key]
    # overwrite key white the ontents of the other
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...