Как добавить значение к еще не существующему ключу?

#python #python-3.x #dictionary #append

#python #python-3.x #словарь #добавить

Вопрос:

У меня есть словарь, подобный этому:

 dct = {'one': 'value', 
       'two': ['value1','value2','value1'], 
       'three':['otherValue1','otherValue2','otherValue1'],
       'dontCareAboutThisKey':'debug'}
  

Мне нужно удалить повторяющиеся значения из списков. Я написал функцию для этого:

 no_dups = {}
    for keys in dct:
        if isinstance(dct[keys], list) and keys != 'dontCareAboutThisKey':
            for value in dct[keys]:
                if value not in no_dups.values():
                    no_dups[keys].append(value)
        else:
            no_dups[keys] = dct[keys]
  

Я проверяю, является ли значение текущего ключа списком. Если нет, он просто «копирует» ключ в no_dups словарь. Если это список, а не ключ, который меня не волнует (дубликатов точно нет) — он должен проверить, существует ли текущее значение в no_dups.values() и добавить его к текущему ключу. Проблема в том, что я получаю сообщение об ошибке:

KeyError: 'two:'

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

Комментарии:

1. В какой строке выдается ошибка?

2. no_dups[keys].append(value)

Ответ №1:

Я думаю, что лучший способ справиться с одновременным добавлением ключа — это использовать setdefault() метод dicts:

 no_dups.setdefault(keys,[]).append(value)
  

Но вместо этого вы можете сделать это более аккуратным способом, вот так:

 #remove duplicates
no_dups = {k:list(set(v)) if isinstance(v, list) and k != 'dontCareAboutThisKey' else v 
           for k,v in dct.items()}  # or dct.iteritems() if using python2.x
  

Этот взлом для комбинаций ключ-значение, которые проходят if тест, преобразует список в набор (удаляя дубликаты), а затем снова в список. Для других комбинаций ключ-значение это оставит его нетронутым.

Комментарии:

1. Это довольно сложно понять, но я попытаюсь. Спасибо 🙂

2. Отлично, в этом нет никакой магии, Python действительно силен в понимании и хорош для их применения.

3. Я знаю, я знаю .. но Learning Python в нем 1500 страниц, и я не могу читать так быстро. Еще раз спасибо за ответ 🙂

Ответ №2:

 dct = {'one': 'value', 
       'two': ['value1','value2','value1'], 
       'three':['otherValue1','otherValue2','otherValue1'],
       'dontCareAboutThisKey':'debug'}
  

set(dct) возвращает set , который представляет собой список без дубликатов:

 for key, value in dct.items():
    if not isinstance(value, basestring):
        dct[key] = set(value)
  

Если вам нужен новый словарь, вы могли бы сделать:

 new_dct = {}
for key, value in dct.items():
    if not isinstance(value, basestring):
        new_dct[key] = set(value)
    else:
        new_dct[key] = value
  

Комментарии:

1. Я не уверен, действительно ли OP хочет создать копию, поскольку это приведет к редактированию на месте … но … мне кажется, это хороший подход

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

Ответ №3:

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

https://docs.python.org/2/tutorial/datastructures.html#sets

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

Комментарии:

1. Спасибо за информацию о наборах. Я запомню это 🙂