2
votes

Recherche de valeurs en double dans le dictionnaire en python et changement de nom

J'ai un dict en python comme ci-dessous -

from random import randint
randint(100, 999)
{'1386': 'USA', '23113': 'Russia', '23295': 'Russia345', '73535': 'Japan' , '12355': 'Japan223', '65447': 'Japan789'}

Les clés sont différentes et uniques mais il peut y avoir des noms communs pour les valeurs dans le dict. Existe-t-il un moyen de trouver le nombre de noms communs et d'ajouter un numéro unique à la fin? Comme -

{'1386': 'USA', '23113': 'Russia', '23295': 'Russia', '73535': 'Japan' , '12355': 'Japan', '65447': 'Japan'}

La première valeur des éléments communs reste telle quelle, mais les autres valeurs seront ajoutées avec un nombre aléatoire à la fin - Russia345, Japan223, Japan789

Je n'ai pas réussi à trouver un moyen de le faire. Dois-je inverser le dict et écrire la logique?

La raison d'essayer cette approche est lorsque j'envoie ces données à Grafana en fonction de la valeur car la valeur est nécessaire pour l'affichage, c'est n'affichant qu'une seule valeur dans la sortie, j'ai donc voulu rendre les valeurs uniques.


1 commentaires

Cela sent un peu comme une solution de contournement. Y a-t-il une meilleure manière de faire cela? Dans le pire des cas, je me pencherais sur les uuids.


3 Réponses :


1
votes

Vous pouvez utiliser un dictionnaire pour stocker les occurrences de chaque valeur:

{'1386': 'USA', '23113': 'Russia', '23295': 'Russia1', '73535': 'Japan', '12355': 'Japan1', '65447': 'Japan2'}

Sortie:

import itertools
c = {b:itertools.count() for b in d.values()}
result = {a:(lambda x:b if not x else b+str(x))(next(c[b])) for a, b in d.items()}

Cependant, cela peut être considérablement simplifié en utilisant simplement un compteur de itertools.count:

{'1386': 'USA', '23113': 'Russia', '23295': 'Russia513', '73535': 'Japan', '12355': 'Japan383', '65447': 'Japan517'}

Output:

import random
d = {'1386': 'USA', '23113': 'Russia', '23295': 'Russia', '73535': 'Japan' , '12355': 'Japan', '65447': 'Japan'}
c, result = {b:[] for b in d.values()}, {}
for a, b in d.items():
   if not c[b]:
     c[b].append('')
     result[a] = b
   else:
     _num = random.randint(100, 999)
     while _num in c[b]:
       _num = random.randint(100, 999)
     c[b].append(_num)
     result[a] = b+str(_num)

p >


3 commentaires

Ajax -i voir une syntaxe invalide dans la ligne result = {a: (lambda x: b sinon x sinon f '{b} {x}') (next (c [b])) pour a, b dans d.items ()} Je n'arrive pas à comprendre car j'essaie de comprendre la commande, pouvez-vous m'aider avec l'erreur de syntaxe


@sdgd Qu'est-ce qui soulève exactement l'erreur de syntaxe? Cela fonctionne pour moi, mais je suppose que le problème est la f-string , qui n'est disponible qu'en Python3.7. Veuillez voir ma récente modification.


nos serveurs sont sur py 2.7 . Votre modification l'a corrigé. Je vous remercie!



2
votes

Avant d'ajouter une paire clé / valeur au dict, vérifiez si la valeur est déjà dans le dict, et si c'est le cas, ajoutez-y quelque chose.

while value in mydict.values():
    value = value + "something"
mydict[key] = value


3 commentaires

mais cela changera également le nom de la première valeur, non?


Non, car pour la toute première valeur, elle ne sera pas encore dans le dict, donc le while ne s'exécutera pas.


Oh ouais!, Compris. Je vous remercie.



0
votes

Une des difficultés ici est de garantir que les suffixes sont aléatoires et uniques . La méthode retry peut boucler indéfiniment. Vous devriez plutôt utiliser random.shuffle . Nous avons besoin d'au plus len (d) -1 nombres aléatoires (dans le cas où toutes les clés sont mappées à la même valeur).

>>> seen = set()
>>> for k, v in d.items():
...     if v in seen:
...             d[k] = v+str(L.pop())
...     else:
...             seen.add(v)
...
>>> d
{'1386': 'USA', '23113': 'Russia', '23295': 'Russia2', '73535': 'Japan', '12355': 'Japan4', '65447': 'Japan5'}

Nous consommerons ces nombres aléatoires uniques numéros "sur demande". Nous stockons la valeur qui a été vue dans un ensemble pour éviter les doublons et chaque fois que nous rencontrons une clé vue , nous sortons un suffixe de la liste:

>>> d = {'1386': 'USA', '23113': 'Russia', '23295': 'Russia', '73535': 'Japan' , '12355': 'Japan', '65447': 'Japan'}
>>> import random
>>> L = list(range(1, len(d)))
>>> random.shuffle(L)
>>> L
[3, 1, 5, 4, 2]

(Relatif: Fisher Yates shuffle )


0 commentaires