2012-06-21 2 views
2

есть ли способ хранения дубликатов ключей в словаре?Есть ли способ сохранить дубликаты ключей в словаре python

У меня есть специальное требование для формирования пар запросов и ответов.

Запросы от конкретного узла к другому конкретному узлу образуют одинаковые ключи. Мне нужно сохранить оба этих.

Но если я попытался добавить их в словарь, то первый заменяется вторым. Там в любом случае?

+7

бы не * словарь * по определению * не * позволяют дубликаты ключей? – Levon

+0

Как только я вижу слово «узел», я думаю «граф». Не могли бы вы прокомментировать дальнейшую цель, а не проблемы с реализацией, которые вы чувствуете, что у вас может быть –

ответ

8

Я могу представить два простых варианта, предполагая, что вы хотите продолжать использовать словарь.

  1. Вы можете сопоставить ключи со списком предметов.A defaultdict от модуля collections делает это легко.

    >>> import collections 
    >>> data = collections.defaultdict(list) 
    >>> for k, v in (('a', 'b'), ('a', 'c'), ('b', 'c')): 
    ...  data[k].append(v) 
    ... 
    >>> data 
    defaultdict(<type 'list'>, {'a': ['b', 'c'], 'b': ['c']}) 
    
  2. Для устранения неполадок ключей вы можете использовать дополнительные данные. Это может быть временная метка, уникальный идентификационный номер или что-то еще. Преимущество этого заключается в сохранении взаимно однозначной взаимосвязи между ключами и значениями и недостатком более сложного поиска, поскольку вы всегда должны указывать id. Пример ниже показывает, как это может работать; ли это хорошо для вас, зависит от проблемной области:

    >>> for k, v in (('a', 'b'), ('a', 'c'), ('b', 'c')): 
    ...  i = 0 
    ...  while (k, i) in data: 
    ...   i += 1 
    ...  data[(k, i)] = v 
    ... 
    >>> data 
    {('a', 1): 'c', ('b', 0): 'c', ('a', 0): 'b'} 
    
4

Нет способа сделать это, нет. Словари полагаются на уникальные ключи - иначе, когда вы запрашиваете или устанавливаете ключ, какое значение будет возвращено или перезаписано?

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

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

+0

. Какими будут ключи к этому словарю? – newbie555

+0

ok я получаю это ... я могу использовать count как ключ к словарю, и для каждого списка, который я добавляю в качестве значения, для следующей записи я могу увеличить счет. – newbie555

+0

@rockluke Что вы описываете, есть список, а не словарь. Если ваши клавиши являются индикаторами, то список более подходит. –

8

Хотя я не уверен на 100%, я уверен, что ответ отрицательный. Этот тип нарушает цель словаря в python. Как насчет того, чтобы изменить значение в списках так что вместо

{Key:value} 

у вас есть

{Key:[Value1,value2]} 
3

Используйте списки для хранения всех значений для одинаковых ключей:

{a:b, a:c} # foolish, won't work 
{a: [ b, c ]} # works like a charm! 

Вы также можете захотеть использование

from collections import defaultdict 
d = defaultdict(list) 
d[a].append(b) 

, чтобы легко заполнить словарь.

+0

ОК, я понимаю ... я могу использовать count как ключ к словарю, и для каждого списка, который я добавляю в качестве значения, для следующей записи я могу увеличить счет. – newbie555

0

Словарь по определению требует, чтобы ключи были уникальными идентификаторами. Вы можете:

  1. Используйте другую структуру данных, такую ​​как список или кортеж, который позволяет дублировать записи.
  2. Используйте уникальный идентификатор для ключей словаря, точно так же, как база данных может использовать автоматически увеличивающееся поле для своего ключевого идентификатора.

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

5

Альтернативой defaultdict может быть

d = {} 
d.setdefault(newkey, []).append(newvalue) 

Это делает то же самое: добавить newvalue в список, который либо уже в словаре на данный newkey, или если нет, то будет введен там.

1

мне нравятся ответы, используя collections.defaultdict. Так я, вероятно, поеду.

Но это предполагает диктофонную или диктоподобную структуру, и правильное решение является однозначным отображением. Перечитывая вопрос, требование «сформировать пары запросов и ответов» может привести к более простому подходу (или списку списков). Например .:

pairs = [] 
pairs.append((request, response)) 

Что может создать список, как:

[ ('GET /', 200), ('GET /index.html', 200), ('GET /x', 403), ('GET /', 200), ] 

Это только слегка структурированной, но в зависимости от того, что вы хотите сделать с ним, может быть хорошо.

0

Более элегантное решение:

def add_to_dict(towhat, key, value): 
    info = towhat.get(key, []) 
    info.append(value) 
    towhat[key] = info 

alternate = {} 

add_to_dict(alternate,"Andrew","Cambridge") 
add_to_dict(alternate,"Barbara","Bloomsbury") 
add_to_dict(alternate,"Andrew","Corsica") 

print alternate 
Смежные вопросы