简体   繁体   中英

iterate over dict to find identical values in python

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

在此处输入图像描述

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?

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)

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']

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'

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)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM