Вопрос по python – сделать словарь с дубликатами ключей в python

39

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

EDF768, Bill Meyer, 2456, Vet_Parking
TY5678, Jane Miller, 8987, AgHort_Parking
GEF123, Jill Black, 3456, Creche_Parking
ABC234, Fred Greenside, 2345, AgHort_Parking
GH7682, Clara Hill, 7689, AgHort_Parking
JU9807, Jacky Blair, 7867, Vet_Parking
KLOI98, Martha Miller, 4563, Vet_Parking
ADF645, Cloe Freckle, 6789, Vet_Parking
DF7800, Jacko Frizzle, 4532, Creche_Parking
WER546, Olga Grey, 9898, Creche_Parking
HUY768, Wilbur Matty, 8912, Creche_Parking
EDF768, Jenny Meyer, 9987, Vet_Parking
TY5678, Jo King, 8987, AgHort_Parking
JU9807, Mike Green, 3212, Vet_Parking 

Код, который я пробовал:

data_dict = {}
data_list = []

def createDictionaryModified(filename):
  path = "C:\Users\user\Desktop"
  basename = "ParkingData_Part3.txt"
  filename = path + "//" + basename
  file = open(filename)
  contents = file.read()
  print contents,"\n"
  data_list = [lines.split(",") for lines in contents.split("\n")]
  for line in data_list:
    regNumber = line[0]
    name = line[1]
    phoneExtn = line[2]
    carpark = line[3].strip()
    details = (name,phoneExtn,carpark)
    data_dict[regNumber] = details
  print data_dict,"\n"
  print data_dict.items(),"\n"
  print data_dict.values()
Если бы словарь позволял дублировать ключи с различными связанными значениями, какой из них вы ожидаете получить, когда будете искать значение для такого ключа позже? martineau

Ваш Ответ

6   ответов
1

http://www.wellho.net/mouth/3934_Multiple-identical-keys-in-a-Python-dict-yes-you-can-.html В dict, если ключ является объектом, проблем с дублированием нет например, & # xFF1A;

class p(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return self.name
    def __str__(self):
        return self.name
d = {p('k'): 1, p('k'): 2}
Как получить все значения с помощью ключа «k»? Единственный способ сделать это - последовательное сравнение, которое теряет смысл использования хэш-словаря.
7

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

Таким образом, вы можете выполнить следующие шаги:

See if the current element's (of your initial set) key is into final dict. If does, go to step 3 Update dict with key Append to dict[key] list the new value Repeat [1-3]
1

?

for line in data_list:
  regNumber = line[0]
  name = line[1]
  phoneExtn = line[2]
  carpark = line[3].strip()
  details = (name,phoneExtn,carpark)
  if not data_dict.has_key(regNumber):
    data_dict[regNumber] = [details]
  else:
    data_dict[regNumber].append(details)
Ноdefaultdict решение лучше, чем делать это вручную (ответ AIX)
я этот работает отлично. Спасибо nrj
Да,not in лучше и в самом деле нетhash_key метод в Python 3.x. Спасибо!
Ты имеешь в видуhas_keyнеhash_key.
вместоhash_keyмы можем просто использоватьif not regNumber in data_dict
33

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

class Dictlist(dict):
    def __setitem__(self, key, value):
        try:
            self[key]
        except KeyError:
            super(Dictlist, self).__setitem__(key, [])
        self[key].append(value)

Из приведенного примера:

>>> d = dictlist.Dictlist()
>>> d['test'] = 1
>>> d['test'] = 2
>>> d['test'] = 3
>>> d
{'test': [1, 2, 3]}
>>> d['other'] = 100
>>> d
{'test': [1, 2, 3], 'other': [100]}
Разве это не то же самое, что: «из коллекций import defaultdict d = defaultdict (list) d [« test »). Append (1) d [« test »». Append (2) .append (3) & APOS; Или я могу что-то упустить?
Почему не простоif key not in self: вместоtry:/except KeyError:?
2

have lists only when they are necessaryи значения в любых других случаях, то вы можете сделать это:

class DictList(dict):
    def __setitem__(self, key, value):
        try:
            # Assumes there is a list on the key
            self[key].append(value) 
        except KeyError: # if fails because there is no key
            super(DictList, self).__setitem__(key, value)
        except AttributeError: # if fails because it is not a list
            super(DictList, self).__setitem__(key, [self[key], value])

Затем вы можете сделать следующее:

dl = DictList()
dl['a']  = 1
dl['b']  = 2
dl['b'] = 3

Который будет хранить следующее{'a': 1, 'b': [2, 3]}.

Я склонен использовать эту реализацию, когда я хочу иметьreverse/inverse dictionariesв этом случае я просто делаю:

my_dict = {1: 'a', 2: 'b', 3: 'b'}
rev = DictList()
for k, v in my_dict.items():
    rev_med[v] = k

Который будет генерировать тот же вывод, что и выше:{'a': 1, 'b': [2, 3]}.

CAVEAT: Эта реализация основана на несуществованииappend метод (в значениях, которые вы храните). Это может привести кunexpected results if the values you are storing are lists, Например,

dl = DictList()
dl['a']  = 1
dl['b']  = [2]
dl['b'] = 3

даст тот же результат, что и раньше{'a': 1, 'b': [2, 3]}, но можно ожидать следующего:{'a': 1, 'b': [[2], 3]}.

91

анить списки или наборы внутри словаря.

Один из простых способов добиться этого - использоватьdefaultdict:

from collections import defaultdict

data_dict = defaultdict(list)

Все, что вам нужно сделать, это заменить

data_dict[regNumber] = details

с

data_dict[regNumber].append(details)

и вы получите словарь списков.

Это действительно мило. Спасибо за идею.
+1 Я написал очень жуткую структуру данных. Хотя ваш подход делает мою структуру данных жуткой! Но намного меньше: D
+1 Хороший способ сделать это, я не буду больше писать об этом после прочтения :)
Сначала я не понимал, что это эквивалентно объявлению значения ключа словаря в виде списка и добавлению к нему. Устраняет несколько строк, хотя, что приятно.if not my_key in data_dict: data_dict[my_key] = list()

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