Home > OS >  Dictionary iteration with conditions
Dictionary iteration with conditions

Time:07-11

I have a dictionary where the key is tuple of child and parent table where it's value is a tuple of lists of child fields and list of parent fields.

RELS = {( "ACCESS_PROFILE_RELATIONSHIP","INVOLVED_PARTY_RELATIONSHIP"):(["INVOLVED_PARTY_RELATIONSHIP_ID","INVOLVED_PARTY_RELATIONSHIP_UUID"],["ID","INVOLVED_PARTY_RELATIONSHIP_UUID"]),
       ("AGREEMENT_IDENTFIER","AGREEMENT"):(["AGREEMENT_ID"],["ID"]),
       ("AGREEMENT_PARTY_ROLE_RELATIONSHIP","INVOLVED_PARTY"):(["INVOLVEP_PARTY_ID","PARTY_UUID"],["ID","PARTY_UUID"]),
       ("AGREEMENT_PARTY_ROLE_RELATIONSHIP","AGREEMENT"):(["AGREEMENT_ID","AGREEMENT_UUID"],["ID","AGREEMENT_UUID"])}

I need to transform it into a dictionary of dictionaries where keys are child tables, it's value is dictionary of child fields that has value of a tuple (parent table, parent field)

{
  'ACCESS_PROFILE_RELATIONSHIP': {
    'INVOLVED_PARTY_RELATIONSHIP_ID': ('INVOLVED_PARTY_RELATIONSHIP','ID'),
    'INVOLVED_PARTY_RELATIONSHIP_UUID': ('INVOLVED_PARTY_RELATIONSHIP','INVOLVED_PARTY_RELATIONSHIP_UUID')
  },
  'AGREEMENT_IDENTFIER': {
    'AGREEMENT_ID': ('AGREEMENT','ID')
  },
  'AGREEMENT_PARTY_ROLE_RELATIONSHIP': {
    'INVOLVED_PARTY_ID': ('INVOLVED_PARTY',ID'),
    'PARTY_UUID:('INVOLVED_PARTY','PARTY_UUID'), 
    'AGREEMENT_ID': ('AGREEMENT', 'ID'),   
    'AGREEMENT_UUID':  ('AGREEMENT', 'AGREEMENT_UUID')
  }
}

I have performed a loop like this:

refs = {}
for tables,fields in RELS.items():
    refs[tables[0]] = {}
    for i,_ in enumerate(fields[0]):
        fk = {fields[0][i]:(tables[1],fields[1][i])}
        if tables[0] in refs.keys():
            refs[tables[0]].update(fk)

yet since dictionary can not have 2 same keys - AGREEMENT_PARY_ROLE_RELATIONSHIP relationship with INVOLVED_PARTY is overwritten by relationship of AGREEMENT_PARTY_ROLE_RELATIONSHIP and AGREEMENT. How can I add a condition in my loop to add a dictionary of {child field:(parent_table,parent_field)} in case if child_table key already exist in my end result?

Thank you in advance!

CodePudding user response:

You are not checking if the key currently exists already. If a table is referenced multiple times the line

refs[tables[0]] = {}

inside your loop will clear the already existing value stored in a previous loop run.

Change it to

RELS = {("ACCESS_PROFILE_RELATIONSHIP","INVOLVED_PARTY_RELATIONSHIP"):(["INVOLVED_PARTY_RELATIONSHIP_ID","INVOLVED_PARTY_RELATIONSHIP_UUID"],  ["ID","INVOLVED_PARTY_RELATIONSHIP_UUID"]),
        ("AGREEMENT_IDENTFIER","AGREEMENT"):(["AGREEMENT_ID"],["ID"]),
        ("AGREEMENT_PARTY_ROLE_RELATIONSHIP","INVOLVED_PARTY"):(["INVOLVEP_PARTY_ID","PARTY_UUID"],["ID","PARTY_UUID"]),
    ("AGREEMENT_PARTY_ROLE_RELATIONSHIP","AGREEMENT"):(["AGREEMENT_ID","AGREEMENT_UUID"],["ID","AGREEMENT_UUID"])}


refs = {}
for tables, fields in RELS.items():
    inner = refs.setdefault(tables[0],{})  # create if not exist, else get its reference
    for i,_ in enumerate(fields[0]):
        fk = {fields[0][i]:(tables[1],fields[1][i])}
        inner.update(fk)

print(refs)

Output:

{'ACCESS_PROFILE_RELATIONSHIP': {'INVOLVED_PARTY_RELATIONSHIP_ID': ('INVOLVED_PARTY_RELATIONSHIP', 'ID'), 
                                 'INVOLVED_PARTY_RELATIONSHIP_UUID': ('INVOLVED_PARTY_RELATIONSHIP', 'INVOLVED_PARTY_RELATIONSHIP_UUID')}, 
 'AGREEMENT_IDENTFIER': {'AGREEMENT_ID': ('AGREEMENT', 'ID')}, 
 'AGREEMENT_PARTY_ROLE_RELATIONSHIP': {'INVOLVEP_PARTY_ID': ('INVOLVED_PARTY', 'ID'), 
                                       'PARTY_UUID': ('INVOLVED_PARTY', 'PARTY_UUID'), 
                                       'AGREEMENT_ID': ('AGREEMENT', 'ID'), 
                                       'AGREEMENT_UUID': ('AGREEMENT', 'AGREEMENT_UUID')}}

This is essentially what @Anentropic ment with his conceise comment.

See setdefault-docu.

  • Related