Searching dictionary for max value then grabbing associated key - python

I need help grabbing the maximum value from a dictionary. I have a dictionary of {num : [state,value] ...} and need to grab everything associated with the highest value.
#find max value in dictionary
td = {0: ['b',3], 1: ['b',6], 4: ['b',2], 3: ['b',5] }
#In this example td dict, I want to grab the key and state associated with the highest value, 6. I want to grab "1: ['b',6]"
print td
print td.keys()
print td.values()
maxval = max([v for k,[s,v] in td.iteritems()])
print maxval #correctly prints 6

Just change your max() comprehension to yield tuples with the value as the first element:
>>> max((v, k, s) for k, (s, v) in td.iteritems())
(6, 1, 'b')
So your code might look something like this:
maxval, maxnum, maxstate = max((v, k, s) for k, (s, v) in td.iteritems())

>>> td = {0: ['b',3], 1: ['b',6], 4: ['b',2], 3: ['b',5] }
>>> max(td, key=lambda k:td[k][1])
1 ## This is the key with the maximum "value"
Of course you can also get the value like this
>>> td[max(td, key=lambda k:td[k][1])]
['b', 6]

print max(td.items(), key = lambda item: item[1][1])
The key parameter takes a function, and if used it will produce the values that maximizes that function.

Related

Dictionary function to find the key,value pair with least value

How to print the cheapest item in the dictionary when the dictionary consists of keys and values as items and their prices?
I tried using operator function for sorting but it converts the dictionary to tuple and then i am unable to display the dictionary key/value.
is there any other approach?
You can use min with the dictionary's .items(), and pass the value of the pair to sort against.
>>> data = {'foo': 17.5, 'bar': 5.8, 'abc': 12.6}
>>> min(data.items(), key=lambda i: i[1])
('bar', 5.8)
Below are your answers:
Novice way:
shoes_list = {'adidas':1000, 'Nike':3000, 'local': 100}
cheapest = ""
for key in shoes_list:
if cheapest == "" or shoes_list[cheapest] > shoes_list[key]:
cheapest = key
print(cheapest)
Intermediate:
shoes_list = {'adidas':1000, 'Nike':3000, 'local': 100}
Cheapest = min(shoes_list, key=shoes_list.get)
print(Cheapest)
Most efficient way:
import operator
shoes_list = {'adidas':1000, 'Nike':3000, 'local': 100}
print(min(shoes_list.items(), key=operator.itemgetter(1))[0])
My initial thought was a dictionary comprehension:
>>> data = {'foo': 17.5, 'bar': 5.8, 'abc': 12.6}
>>> min_val = min(data.values())
>>> {k: v for k, v in data.items() if v == min_val}
{'bar': 5.8}
However, CoryKramer's only iterates over the dictionary once, whereas my answer needs two runs
#1) Convert the dictionary values into list,find the minimum
#2) Find the index value of the minimum value.
#3) Finally convert the list value to strings and print it.
#SOURCE CODE
dd={'mobile1':10000, 'mobile2':11000, 'mobile3':13000, 'mobile4':9000, 'mobile5':15000, 'mobile6':16000, 'mobile7':17000, 'mobile8':18000, 'mobile9':19000}
k=list(dd.values())
d={}
def get_key(val):
for key, value in dd.items():
if val == value:
return key
mm=k[0]
for i in range(1,len(k)):
if k[i]<mm:
mm=k[i]
l=mm
index_value = list(dd.keys()).index(get_key(l))
f=list(list(dd.items())[index_value])
print(str(f[0])+":"+str(f[1]))

How to create a lookup table with noise in Python?

Say I have a dictionary in Python {1:'a', 100:'b', 1024:'c'}
I want to build a function that can look for not only the exact value of the key, but also approximated values. For instance, the function can return b if the input is 99 or 101.
Could you suggest me some approaches?
If you want to keep the speed advantage of a dict, you could bin your keys, e.g. by rounding them to the nearest multiple of 10:
>>> data = {1:'a', 100:'b', 1024:'c'}
>>> fuzzy = { ((k + 5) // 10) * 10:v for k,v in data.items() }
>>> fuzzy
{0: 'a', 100: 'b', 1020: 'c'}
When you want to check if a values is close to a key in data, you simply apply the same transformation:
>>> fuzzy.get(((98+5)//10)*10)
'b'
>>> fuzzy.get(((97+5)//10)*10)
'b'
>>> fuzzy.get(((100+5)//10)*10)
'b'
>>> fuzzy.get(((101+5)//10)*10)
'b'
>>> fuzzy.get(((1022+5)//10)*10)
'c'
If you have a finite range for the values of the keys that is known in advance something like this indexing with tuples
>>> d={(0,2):'a', (99,101):'b', (1023,1025):'c'}
To find the value of a key:
Find 1024.01:
>>> d={(0,2):'a', (99,101):'b', (1023,1025):'c'}
>>> next(v for (k,v) in d.iteritems() if k[0]<=1024.01<=k[1])
'c'
Find 1025.01:
>>> next(v for (k,v) in d.iteritems() if k[0]<=1025.01<=k[1])
# throws an error because key is not found
You can make your own lookup function as follows:
import sys
def lookup(value, dict):
nearest = sys.maxint
result = ""
for k,v in dict.iteritems():
if abs(value - k) < nearest:
nearest = abs(value - k)
result = v
return result
print lookup(101, {1:'a', 100:'b', 1024:'c'})
You can search for values within 2% range (configurable) with something like this:
data = {1:'a', 100:'b', 1024:'c'}
def get_approx(data, key):
return [elem[1] for elem in data.iteritems() if elem[0]*0.98 <= key <= elem[0]*1.02]
get_approx(data, 99) # outputs ['b']

Adding nonzero items from a dictionary to another dictionary

I have a set of reactions (keys) with values (0.0 or 100) stored in mydict.
Now I want to place non zero values in a new dictionary (nonzerodict).
def nonzero(cmod):
mydict = cmod.getReactionValues()
nonzerodict = {}
for key in mydict:
if mydict.values() != float(0):
nonzerodict[nz] = mydict.values
print nz
Unfortunately this is not working.
My questions:
Am I iterating over a dictionary correctly?
Am I adding items to the new dictionary correctly?
You are testing if the list of values is not equal to float(0). Test each value instead, using the key to retrieve it:
if mydict[key] != 0:
nonzerodict[key] = mydict[key]
You are iterating over the keys correctly, but you could also iterate over the key-value pairs:
for key, value in mydict.iteritems():
if value != 0:
nonzerodict[key] = value
Note that with floating point values, chances are you'll have very small values, close to zero, that you may want to filter out too. If so, test if the value is close to zero instead:
if abs(value) > 1e-9:
You can do the whole thing in a single dictionary expression:
def nonzero(cmod):
return {k: v for k, v in cmod.getReactionValues().iteritems() if abs(v) > 1e-9}
Its simple and you can it by below way -
>>> d = {'a':4,'b':2, 'c':0}
>>> dict((k,v) for k,v in d.iteritems() if v!=0)
{'a': 4, 'b': 2}
>>>
Replace if condition in you code with:
if mydict[key]:
nonzerodict[key] = mydict[key]
Your solution can be further simplified as:
def nonzero(cmod):
mydict = cmod.getReactionValues()
nonzerodict = {key: value for key, value in mydict.iteritems() if value}

Remove the smallest element(s) from a dictionary

I have a function such that there is a dictionary as parameters, with the value associated to be an integer. I'm trying to remove the minimum element(s) and return a set of the remaining keys.
I am programming in python. I cant seem to remove key value pairs with the same key or values. My code does not work for the 2nd and 3rd example
This is how it would work:
remaining({A: 1, B: 2, C: 2})
{B, C}
remaining({B: 2, C : 2})
{}
remaining({A: 1, B: 1, C: 1, D: 4})
{D}
This is what I have:
def remaining(d : {str:int}) -> {str}:
Remaining = set(d)
Remaining.remove(min(d, key=d.get))
return Remaining
One approach is to take the minimum value, then build a list of keys that are equal to it and utilise dict.viewkeys() which has set-like behaviour and remove the keys matching the minimum value from it.
d = {'A': 1, 'B': 1, 'C': 1, 'D': 4}
# Use .values() and .keys() and .items() for Python 3.x
min_val = min(d.itervalues())
remaining = d.viewkeys() - (k for k, v in d.iteritems() if v == min_val)
# set(['D'])
On a side note, I find it odd that {B: 2, C : 2} should be {} as there's not actually anything greater for those to be the minimum as it were.
That's because you're trying to map values to keys and map allows different keys to have the same values but not the other way! you should implement a map "reversal" as described here, remove the minimum key, and then reverse the map back to its original form.
from collections import defaultdict
# your example
l = {'A': 1, 'B': 1, 'C': 1, 'D': 4}
# reverse the dict
d1 = {}
for k, v in l.iteritems():
d1[v] = d1.get(v, []) + [k]
# remove the min element
del d1[min(d1, key=d1.get)]
#recover the rest to the original dict minus the min
res = {}
for k, v in d1.iteritems():
for e in v:
res[e] = k
print res
Comment:
#Jon Clements's solution is more elegant and should be accepted as the answer
Take the minimum value and construct a set with all the keys which are not associated to that value:
def remaining(d):
m = min(d.values())
return {k for k,v in d.items() if v != m}
If you don't like set comprehensions that's the same as:
def remaining(d):
m = min(d.values())
s = set()
for k,v in d.items():
if v != m:
s.add(k)
return s
This removes all the items with the minimum value.
import copy
def remaining(dic):
minimum = min([i for i in dic.values()])
for k, v in copy.copy(dic.items()):
if v == minimum: dic.pop(k)
return set(dic.keys())
An easier way would be to use pd.Series.idxmin() or pd.Series.min(). These functions allow you to find the index of the minimum value or the minimum value in a series, plus pandas allows you to create a named index.
import pandas as pd
import numpy as np
A = pd.Series(np.full(shape=5,fill_value=0))#create series of 0
A = A.reindex(['a','b','c','d','e'])#set index, similar to dictionary names
A['a'] = 2
print(A.max())
#output 2.0
print(A.idxmax())#you can also pop by index without changing other indices
#output a

Python dictionaries - find second character in a 2-character string which yields minimum value

I would like to submit the first part of a key and return the remaining part of that key which minimizes the value (and starts with the first part).
For example:
d = {'ab': 100,
'ac': 200,
'ad': 500}
If I were to pass in 'a', I would like to return'b'`.
min(((d[s],s) for s in d if s.startswith('a')))[1][1:]
The min finds the minimum value in the (value, key) pairs, and then we take the key (with the smallest value), and display the latter part of it. This uses the fact that min, minimises over the first value in a tuple.
And we could generalise to find the minimum which "starts with a string" a as:
def smallest_value_of_key_startswith(a, d):
min(((d[s],s) for s in d if s.startswith(a)))[1][len(a):]
Use this:
def f(d, key):
return min(((v, k[1]) for k, v in d.items() if k[0] == key))[1]
distance = {('a','b'):100,('a','c'):200,('a','d'):500}
print f(distance, 'a')
>>> 'b'
distance = {('c','e'):200,('d','c'):100,('c','d'):500}
print f(distance, 'c')
>>> 'e'

Categories

Resources