Home > Software engineering >  iterate over dict to find identical values in python
iterate over dict to find identical values in python

Time:08-12

let's assume I have x = (600, 800 , 700) and I have also the following dict:

enter image description here

I want to find the equivalent values for x from the dict (which is highlighted in the picture) knowing that the values in dict might be swapped in an unknown order.

Is that possible without writing complex searching code?

CodePudding user response:

You could sort the values you're looking for and sort each entry in the dictionary before the comparison:

value_to_find = (600, 800, 700)

dict_to_search = {
    'key_01':(40, 300, 300),
    'key_02':(800, 500, 1000),
    'key_03':(500, 1000, 200),
    'key_04':(800, 700, 600)
}

value_to_find = sorted(value_to_find)
for key in dict_to_search:
    sorted_value = sorted(dict_to_search[key])
    if sorted_value == value_to_find:
        print(f'matching values found against {key}: {dict_to_search[key]}')
        break

Output:

matching values found against key_04: (800, 700, 600)

CodePudding user response:

IIUC, you can achieve this in pure python and without any loop using the following code:

d = {
    "key0": (40, 300, 300),
    "key1": (800, 500, 1000),
    "key2": (500, 1000, 200),
    "key3": (800, 700, 600),
}
x = (600, 800 , 700)
pos = list(map(sorted, d.values())).index(list(sorted(x)))
list(d.keys())[pos] # 'key3'

If you want to check several matches, you could make use of numpy slicing (also no iteration needed):

Code:

import numpy as np

d = {
    "key0": (40, 300, 300),
    "key1": (800, 500, 1000),
    "key2": (500, 1000, 200),
    "key3": (800, 700, 600),
    "key4": (400, 200, 80),
    "key5": (600, 800, 700),
    "key6": (600, 700, 800),
}

positions = (np.array(list(map(sorted, d.values()))) == np.array(sorted(x))).any(axis=1)
list(np.array(list(d.keys()))[positions])

Output:

['key3', 'key5', 'key6']

CodePudding user response:

if we want just to know if there is a match for numbers in values_to_find and in dict_to search, we can use all(...), and no sorting is required:

value_to_find = (600, 800, 700)

dict_to_search = {
    'key_01':(40, 300, 300),
    'key_02':(800, 500, 1000),
    'key_03':(500, 1000, 200),
    'key_04':(800, 700, 600)
}

for k, v in dict_to_search.items():
    if all([i in value_to_find for i in v]):
        print(k)

the result is: 'key_04'

CodePudding user response:

Since the order of the numbers is irrelevant, you can convert the tuples to sets (which are unordered) and then simply check for equality.

value_to_find = (600, 800, 700)

dict_to_search = {
    'key_01':(40, 300, 300),
    'key_02':(800, 500, 1000),
    'key_03':(500, 1000, 200),
    'key_04':(800, 700, 600)
}

result = []
for key,value in dict_to_search.items():
    if set(value) == set(value_to_find):
        result.append(key)

print(result)

This outputs ['key_04']

You could also use list comprehension to do it in one line

result = [key for key,value in dict_to_search.items() if set(value)==set(value_to_find)]
  • Related