Home > front end >  Pair Generation from dictionaries with binary values
Pair Generation from dictionaries with binary values

Time:04-27

I have an input dictionary like this:

dict1= {'AM': ['tv', 'rs', 'pq', 'MN', 'tN', 'tq', 'OP', 'tP', 'QR', 'tr'],
        'BR': ['tv', 'rs', 'pq', 'MN', 'tN', 'tq', 'OP', 'tP', 'QR', 'tr']}

Two other dictionaries in which I want to search

dict2={'AM':{'pq','rs','tv'},'BR':{'MN','OP','QR'}}
dict3={'AM':{'tq','rs','tv'},'BR':{'tN','tP','tr'}}

Expected Output

{'AM-tv': 1,
 'AM-rs': 1,
 'AM-pq': 1,
 'AM-MN': 0,
 'AM-tN': 0,
 'AM-tq': 1,
 'AM-OP': 0,
 'AM-tP': 0,
 'AM-QR': 0,
 'AM-tr': 0,
 'BR-tv': 0,
 'BR-rs': 0,
 'BR-pq': 0,
 'BR-MN': 1,
 'BR-tN': 1,
 'BR-tq': 0,
 'BR-OP': 1,
 'BR-tP': 1,
 'BR-QR': 1,
 'BR-tr': 1}

In output, there is a need to generate pairs from dict1. if the values of dict1 keys are present in values of dict2 or dict3 keys then its value will be 1 in output. if values are not present then its value will be 0 in new dict. is there anyway to do it?

CodePudding user response:

One option is to do a set membership check for each element in the lists in dict1 as we traverse dict1:

out = {}
for k, lst in dict1.items():
    s =  dict2[k] | dict3[k]
    for v in lst:
        out[f"{k}-{v}"] = (v in s) * 1

We can also write the same code as a dict comprehension (but it's slower than the other option since we do set union len(lst) times instead of once as in the loop):

out = {f"{k}-{v}": (v in dict2[k] | dict3[k]) * 1 for k, lst in dict1.items() for v in lst}

Output:

{'AM-tv': 1,
 'AM-rs': 1,
 'AM-pq': 1,
 'AM-MN': 0,
 'AM-tN': 0,
 'AM-tq': 1,
 'AM-OP': 0,
 'AM-tP': 0,
 'AM-QR': 0,
 'AM-tr': 0,
 'BR-tv': 0,
 'BR-rs': 0,
 'BR-pq': 0,
 'BR-MN': 1,
 'BR-tN': 1,
 'BR-tq': 0,
 'BR-OP': 1,
 'BR-tP': 1,
 'BR-QR': 1,
 'BR-tr': 1}

CodePudding user response:

You can two simple nested loops for this.

Here is a variant that should work with most python versions:

out = {}
dicts = [dict2, dict3]

for k,l in dict1.items():
    for v in l:
        out[f'{k}-{v}'] = 1 if any(v in d[k] for d in dicts) else 0

or, as a dictionary comprehension:

out = {f'{k}-{v}': 1 if any(v in d[k] for d in dicts) else 0
       for k,l in dict1.items() for v in l}

output:

{'AM-tv': 1,
 'AM-rs': 1,
 'AM-pq': 1,
 'AM-MN': 0,
 'AM-tN': 0,
 'AM-tq': 1,
 'AM-OP': 0,
 'AM-tP': 0,
 'AM-QR': 0,
 'AM-tr': 0,
 'BR-tv': 0,
 'BR-rs': 0,
 'BR-pq': 0,
 'BR-MN': 1,
 'BR-tN': 1,
 'BR-tq': 0,
 'BR-OP': 1,
 'BR-tP': 1,
 'BR-QR': 1,
 'BR-tr': 1}

CodePudding user response:

You can achieve the results you want by first creating a set of all the values present in dict2 and dict3 for each key, then checking all the combinations of keys and values in dict1 for presence in that set:

present = { k : dict2[k] | dict3[k] for k in dict2 }
result = { f'{k}-{v}' : (v in present[k]) * 1 for k in dict1.keys() for v in dict1[k] }

Output:

{
 'AM-tv': 1, 'AM-rs': 1, 'AM-pq': 1, 'AM-MN': 0, 'AM-tN': 0,
 'AM-tq': 1, 'AM-OP': 0, 'AM-tP': 0, 'AM-QR': 0, 'AM-tr': 0,
 'BR-tv': 0, 'BR-rs': 0, 'BR-pq': 0, 'BR-MN': 1, 'BR-tN': 1,
 'BR-tq': 0, 'BR-OP': 1, 'BR-tP': 1, 'BR-QR': 1, 'BR-tr': 1
}

Note - multiplying a boolean by 1 is the same as converting it to an int using int(...), but faster.

  • Related