87 votes

Créer un dictionnaire avec des clés dupliquées en Python

J'ai la liste suivante qui contient des numéros d'immatriculation de voiture en double avec des valeurs différentes. Je veux la convertir en un dictionnaire qui accepte ces clés multiples de numéros d'immatriculation.

Jusqu'à présent, lorsque j'essaie de convertir une liste en dictionnaire, il élimine une des clés. Comment puis-je créer un dictionnaire avec des clés dupliquées ?

La liste est :

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

Le code que j'ai essayé est le suivant :

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()

7voto

toto_tico Points 2014

Si vous voulez n'avoir des listes que lorsqu'elles sont nécessaires et des valeurs dans tous les autres cas, alors vous pouvez le faire :

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

Vous pouvez alors procéder comme suit :

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

Qui stockera les éléments suivants {'a': 1, 'b': [2, 3]} .


J'ai tendance à utiliser cette implémentation lorsque je veux avoir des dictionnaires inversés/inversés Dans ce cas, je le fais tout simplement :

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

Ce qui génère le même résultat que ci-dessus : {'a': 1, 'b': [2, 3]} .


CAVEAT : Cette mise en œuvre repose sur l'inexistence de l'élément append (dans les valeurs que vous stockez). Cela peut donner des résultats inattendus si les valeurs que vous stockez sont des listes . Par exemple,

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

produirait le même résultat que précédemment {'a': 1, 'b': [2, 3]} mais on pourrait s'attendre à ce qui suit : {'a': 1, 'b': [[2], 3]} .

3voto

Oskarbi Points 311

Vous ne pouvez pas avoir de clés dupliquées dans un dictionnaire. Utilisez un dict de listes :

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)

0voto

Le dictionnaire ne prend pas en charge les clés dupliquées, mais vous pouvez utiliser la fonction Verdict par défaut
Vous trouverez ci-dessous un exemple d'utilisation de Verdict par défaut en python3x pour résoudre votre problème

from collections import defaultdict

sdict = defaultdict(list)
keys_bucket = list()

data_list = [lines.split(",") for lines in contents.split("\n")]
for data in data_list:
    key = data.pop(0)
    detail = data

    keys_bucket.append(key)
    if key in keys_bucket:
        sdict[key].append(detail)
    else:
        sdict[key] = detail

print("\n", dict(sdict))

Le code ci-dessus produira le résultat suivant :

{'EDF768': [[' Bill Meyer', ' 2456', ' Vet_Parking'], [' Jenny Meyer', ' 9987', ' Vet_Parking']], 'TY5678': [[' Jane Miller', ' 8987', ' AgHort_Parking'], [' Jo King', ' 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'], [' Mike Green', ' 3212', ' 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']]}

0voto

C'est une vieille question, mais ma solution peut aider quelqu'un.

en passant outre __hash__ méthode magique, vous pouvez sauvegarder les mêmes objets dans le dict.

Exemple :

from random import choices

class DictStr(str):
    """
        This class behave exacly like str class but
        can be duplicated in dict
    """
    def __new__(cls, value='', custom_id='', id_length=64):
        # If you want know why I use __new__ instead of __init__
        # SEE: https://stackoverflow.com/a/2673863/9917276
        obj = str.__new__(cls, value)
        if custom_id:
            obj.id = custom_id
        else:
            # Make a string with length of 64
            choice_str = "abcdefghijklmopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ1234567890"
            obj.id = ''.join(choices(choice_str, k=id_length))
        return obj

    def __hash__(self) -> int:
        return self.id.__hash__()

Maintenant, créons un dict :

>>> a_1 = DictStr('a')
>>> a_2 = DictStr('a')
>>> a_3 = 'a'
>>> a_1
a
>>> a_2
a
>>> a_1 == a_2 == a_3
True
>>> d = dict()
>>> d[a_1] = 'some_data'
>>> d[a_2] = 'other'
>>> print(d)
{'a': 'some_data', 'a': 'other'}

NOTE : Cette solution peut s'appliquer à toute structure de données de base comme (int, float,...).

EXPLICATION :

Nous pouvons utiliser presque n'importe quel objet comme clé dans dict (ou plus connu sous le nom de HashMap o HashTable dans d'autres langages) mais il devrait y avoir un moyen de distinguer les clés parce que dict n'a aucune idée des objets.

Dans ce but, les objets qui veulent être ajoutés au dictionnaire en tant que clé doivent fournir un numéro d'identification unique (je l'ai nommé uniq_id, c'est en fait un numéro créé par un algorithme de hachage) pour eux-mêmes.

Parce que la structure du dictionnaire est largement utilisée dans la plupart des solutions, la plupart des langages de programmation cachent la génération de l'uniq_id des objets dans un dictionnaire. hash nom de la méthode de construction qui alimente le dict dans la recherche de clé

Donc si vous manipulez hash de votre classe, vous pouvez modifier le comportement de votre classe en tant que clé de dictionnaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X