Home > OS >  Dictionary: check if value[1] exist in a two values tuple and if does give the same value[0] of the
Dictionary: check if value[1] exist in a two values tuple and if does give the same value[0] of the

Time:06-11

I'm working with a dict that has a key and two values in a tuple where the first value is just a temporary default one and the second one is a definitive one. The dict looks pretty much like this:

my_dict = {b:("num","bread"), a:("num","arm"), d:("num","desk"), aa:("num","arm"),
           c:("num","check"), aaa:("num","arm"), dd:("num","desk"), f:("num","film")}

What I'd like to do is to add a increasing number instead of "num", but if the second value is a duplicate one (like "arm" or "desk") then the number should be the same of the first occurrence. so the above list should look something like this:

my_dict = {b:(1,"bread"), a:(2,"arm"), d:(3,"desk"), aa:(2,"arm"), c:(4,"check"),
           aaa:(2,"arm"), dd:(3,"desk"), f:(5,"film")}

This is what I could think by myself:

c = 0
saved = []

for key, value in my_dict.items():
    if not value[1] in saved:
        saved.append(value[1])
        self.citations_dictionary[key] = c, value[1]
        c  = 1

It works, but now I don't know how to check for duplicate values and how to assign the number of the first occurrence.

CodePudding user response:

First create a dictionary to hold the incrementing numbers. Then you can use this to create the new dictionary.

indexes = {}
counter = 0
for _, value in my_dict.values():
    if value not in indexes:
        counter  = 1
        indexes[value] = counter

new_dict = {key: (indexes[value], value) for key, (_, value) in my_dict.items()}

CodePudding user response:

You can use a defaultdict with a reference to its own length as counter:

from collections import defaultdict
d = defaultdict(lambda: len(d) 1)
out = {k: (d[v[1]], v[1]) for k,v in my_dict.items()}

Output:

{'b': (1, 'bread'),
 'a': (2, 'arm'),
 'd': (3, 'desk'),
 'aa': (2, 'arm'),
 'c': (4, 'check'),
 'aaa': (2, 'arm'),
 'dd': (3, 'desk'),
 'f': (5, 'film')}

Less hacky alternative using itertools.count:

from collections import defaultdict
from itertools import count
d = defaultdict(lambda c=count(1): next(c))
out = {k: (d[v[1]], v[1]) for k,v in my_dict.items()}
  • Related