-1

I am using and image scanning API to look for specific images i.e. cat or dog this API tells you the probability of a result in your image. For example an image of a dog would return

{u'dog': 0.99628395, u'cat': 0.87454434}

I want my end result only to take the highest returned value AND only if its above .89 AND below 1.

Code I have so far:

import operator

#define lists
tags = [u'dog', u'cat']
tags_value= [0.99628395, 0.87454434]

#merge key and value pairs
keywords = dict(zip(tags, tags_value))

#check the result
print (keywords)

which gives me

{u'dog': 0.99628395, u'cat': 0.87454434}

I am looking for an end result of

[u'dog']

(notice how the end result is in [] and not {})

Note: if the end result is {u'dog': 0.88628395, u'cat': 0.87454434} then I don't want to return anything because the value is less than .89

Joe Elia
  • 53
  • 7

5 Answers5

2

There are two steps:

To get the key with the max value of a dictionary you can do best = max(keywords, key=keywords.get). This will get the max value of the dictionary, as it uses the key to get the value for each item in the dictionary.

Then you can simply check if its within your bounds: return best if .89 < keywords[best] < 1 else []. This will return an empty array if the value is not between .89 and 1

TwoShorts
  • 508
  • 2
  • 7
  • 20
1

Updated

For efficiency (from @Mad Physicist's comment), you may take the max element and check if it is in the expected range.

data = {u'dog': 0.99628395, u'cat': 0.87454434}
probable_key = max(data, key = data.get)
result = None
if 0.89<data[probable_key] and data[probable_key]<1:
    result = probable_key
print(result) # dog

You can also sort the dictionary by its value and then check if the value is in expected range.

import operator
data = {u'dog': 0.99628395, u'cat': 0.87454434}

sorted_data = sorted(data.items(), key = operator.itemgetter(1), reverse=True)
result = None
if 0.89<sorted_data[0][1] and sorted_data[0][1]<1:
    result = sorted_data[0][0]
print(result) # dog
arshovon
  • 13,270
  • 9
  • 51
  • 69
1
max((k for k, v in keywords.items() if .89 < v < 1), default=None, key=keywords.get)
# 'dog'
  • The first argument filters the dictionary for items that meet the condition, i.e. .89 < v < 1.
  • The second argument is a default value that is returned if no items meet the condition, e.g. {u'dog': 0.88628395, u'cat': 0.87454434} -> None.
  • The last argument is a key function that applies max() to the values of the original dictionary.
pylang
  • 40,867
  • 14
  • 129
  • 121
  • @StefanPochmann Fixed. Although, filtering with dictionary comprehensions is a common practice. – pylang Dec 27 '17 at 20:46
  • @StefanPochmann The key function is accessing the values of the dictionary. A generator expression is fine too if you return the key based on the value. – pylang Dec 28 '17 at 01:46
  • Ah. Now I see your complaint. – pylang Dec 28 '17 at 01:56
0

Answer 1 (more pythonic):

res = [ key for key, val in keywords.items() if ( (val == max(list(keywords.values()))) and (0.89 <= val) and (val <= 1) ) ]
print (res)

Answer 2 (more "granular"):

keys = list(keywords.keys())
values = list(keywords.values())
print( keys, values )
max_value = max(values)
max_index = values.index(max_value)
max_key = keys[max_index]
res = []
if ( (0.89 <= max_value) and (max_value <= 1) ) :
    res.append(max_key)
print (res)

From what I tested, option 1 is ca. 25% faster (5.3us vs. 6.9us).

0

You can convert items into the tuple format and then use max , tuple always compare by its first item :

sample={u'dog': 0.99628395, u'cat': 0.87454434}
print(max([(j,i) for i,j in sample.items() if j>0.89 and j<1]))

output:

(0.99628395, 'dog')
Aaditya Ura
  • 12,007
  • 7
  • 50
  • 88