how to find value using key in dictionary - python

Hello I am trying to find the values in a dictionary using they keys which is a 2 element tuple.
For example any basic dictionary would look like this:
dict = {'dd':1, 'qq':2, 'rr':3}
So if I would like to find the value of 'dd' I would simply do:
>>>dict['dd']
1
but what if I had a dictionary who's keys were 2 element tuples:
dict = {('dd', 'ee'):1, ('qq', 'bb'):2, ('rr', 'nn'):3}
Then how can I find the value of 'dd' or 'rr'

You aren't using the dictionary properly. The keys in the dictionary should be in the form that you want to look them up. So unless you are looking up values by tuple ('dd', 'ee') you should separate out those keys.
If you are forced to start with that dict structure then you can transform into the desired dict using this:
d1 = {('dd', 'ee'):1, ('qq', 'bb'):2, ('rr', 'nn'):3}
# creates {'dd': 1, 'ee': 1, 'qq': 2, 'bb': 2, 'rr': 3, 'nn': 3}
d2 = {x:v for k, v in d1.items() for x in k}

You need to revert to a linear search
>>> D = {('dd', 'ee'):1, ('qq', 'bb'):2, ('rr', 'nn'):3}
>>> next(D[k] for k in D if 'dd' in k)
1
If you need to do more than one lookup, it's worth building a helper dict as #bcorso suggests
having said that. dict is probably the wrong datastructure for whatever problem you are trying to solve

Use a list comprehension:
>>> d={('dd', 'ee'):1, ('qq', 'bb'):2, ('rr', 'nn'):3, ('kk','rr'):4}
>>> [(t,d[t]) for t in d if 'rr' in t]
[(('kk', 'rr'), 4), (('rr', 'nn'), 3)]

Related

Extract a list of keys by Sorting the dictionary in python

I have my program's output as a python dictionary and i want a list of keys from the dictn:
s = "cool_ice_wifi"
r = ["water_is_cool", "cold_ice_drink", "cool_wifi_speed"]
good_list=s.split("_")
dictn={}
for i in range(len(r)):
split_review=r[i].split("_")
counter=0
for good_word in good_list:
if good_word in split_review:
counter=counter+1
d1={i:counter}
dictn.update(d1)
print(dictn)
The conditions on which we should get the keys:
The keys with the same values will have the index copied as it is in a dummy list.
The keys with highest values will come first and then the lowest in the dummy list
Dictn={0: 1, 1: 1, 2: 2}
Expected output = [2,0,1]
You can use a list comp:
[key for key in sorted(dictn, key=dictn.get, reverse=True)]
In Python3 it is now possible to use the sorted method, as described here, to sort the dictionary in any way you choose.
Check out the documentation, but in the simplest case you can .get the dictionary's values, while for more complex operations, you'd define a key function yourself.
Dictionaries in Python3 are now insertion-ordered, so one other way to do things is to sort at the moment of dictionary creation, or you could use an OrderedDict.
Here's an example of the first option in action, which I think is the easiest
>>> a = {}
>>> a[0] = 1
>>> a[1] = 1
>>> a[2] = 2
>>> print(a)
{0: 1, 1: 1, 2: 2}
>>>
>>> [(k) for k in sorted(a, key=a.get, reverse=True)]
[2, 0, 1]

How do I find the keys in one dictionary that do not have a counterpart in another dictionary?

In Python, how do I find the keys in one dictionary that do not have a counterpart in another dictionary? The practical problem is that I have a dictionary of people that enrolled and a dictionary with their daily participation and I am trying to find the people that enrolled but did not participate, or are in the enrollments dictionary and not in the participation dictionary.
In the Python cookbook I found good code for the intersection enrollments and participation, or the intersection of the two dictionaries:
print "Intersection: ", filter(enrollments.has_key, participation.keys())
But I can't figure out how to extend this logic to the obverse (?) case. I have tried putting a not in front of participation.keys() but I get an error. Is there a way to extend the logic in the filter to my problem or another way to approach it altogether?
Use sets on the keys to find the difference:
>>> P = dict(zip('a b c d'.split(),[1,2,3,4]))
>>> E = dict(zip('a b e f'.split(),[6,7,8,9]))
>>> set(P)-set(E)
{'d', 'c'}
>>> set(E)-set(P)
{'f', 'e'}
Also, you can use a dictionary comprehension. It is a way to map a function across a dictionary, and/or filter the contents. The syntax means to return the key:value pair for each key and value in the dictionary's items where the key is not in another dictionary:
>>> {k:v for k,v in P.items() if k not in E}
{'d': 4, 'c': 3}
>>> {k:v for k,v in E.items() if k not in P}
{'f': 9, 'e': 8}
In Python 3, dict.keys() gives you a set-like view of the keys in a dictionary, so doing this is as simple as:
>>> enrolled = {'steve': 0, 'mike': 42, 'judy': 100}
>>> participated = {'judy': 5, 'mike': 10}
>>> enrolled.keys() - participated.keys()
{'steve'}
In Python 2, replace .keys() with .viewkeys()
You can use a lambda as the first argument to filter.
print "Intersection: ", filter(lambda x:x not in participation, enrollments)

removing key value pairs by matching values python

I am searching for periods "." in a dictionary and trying to delete the key/value pair if I find it
if "." in dict.values():
#delete key, value pair from the dictionary
I am sure this is very simple but I cannot seem to locate an explanation.
Thanks for your help.
Create a new dictionary without those unwanted values using dictionary comprehension. Here is an example of how to do it:
>>> old_dict = {'one': '.', 'two': 2, 'three':3, 'four':'.'}
>>> new_dict = {k:v for k,v in old_dict.iteritems() if not v == '.'}
>>> new_dict
{'three': 3, 'two': 2}
using iteritems instead of items avoids creating an intermediate list and improves performance.
If you don't want to copy your dictionary, (for example if the dictionary is large, or you have a reference to it elsewhere) then you should do it this way:
ks = [k for k in d if d[k]=='.']
for k in ks:
d.pop(k)
Create your list of keys to be removed ahead of time as shown above. You don't want to modify your dictionary while iterating over it.

How to get the index with the key in a dictionary?

I have the key of a python dictionary and I want to get the corresponding index in the dictionary. Suppose I have the following dictionary,
d = { 'a': 10, 'b': 20, 'c': 30}
Is there a combination of python functions so that I can get the index value of 1, given the key value 'b'?
d.??('b')
I know it can be achieved with a loop or lambda (with a loop embedded). Just thought there should be a more straightforward way.
Use OrderedDicts: http://docs.python.org/2/library/collections.html#collections.OrderedDict
>>> x = OrderedDict((("a", "1"), ("c", '3'), ("b", "2")))
>>> x["d"] = 4
>>> x.keys().index("d")
3
>>> x.keys().index("c")
1
For those using Python 3
>>> list(x.keys()).index("c")
1
Dictionaries in python (<3.6) have no order. You could use a list of tuples as your data structure instead.
d = { 'a': 10, 'b': 20, 'c': 30}
newd = [('a',10), ('b',20), ('c',30)]
Then this code could be used to find the locations of keys with a specific value
locations = [i for i, t in enumerate(newd) if t[0]=='b']
>>> [1]
You can simply send the dictionary to list and then you can select the index of the item you are looking for.
DictTest = {
'4000':{},
'4001':{},
'4002':{},
'4003':{},
'5000':{},
}
print(list(DictTest).index('4000'))
No, there is no straightforward way because Python dictionaries do not have a set ordering.
From the documentation:
Keys and values are listed in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions.
In other words, the 'index' of b depends entirely on what was inserted into and deleted from the mapping before:
>>> map={}
>>> map['b']=1
>>> map
{'b': 1}
>>> map['a']=1
>>> map
{'a': 1, 'b': 1}
>>> map['c']=1
>>> map
{'a': 1, 'c': 1, 'b': 1}
As of Python 2.7, you could use the collections.OrderedDict() type instead, if insertion order is important to your application.
#Creating dictionary
animals = {"Cat" : "Pat", "Dog" : "Pat", "Tiger" : "Wild"}
#Convert dictionary to list (array)
keys = list(animals)
#Printing 1st dictionary key by index
print(keys[0])
#Done :)

Return first N key:value pairs from dict

Consider the following dictionary, d:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
I want to return the first N key:value pairs from d (N <= 4 in this case). What is the most efficient method of doing this?
There's no such thing a the "first n" keys because a dict doesn't remember which keys were inserted first.
You can get any n key-value pairs though:
n_items = take(n, d.items())
This uses the implementation of take from the itertools recipes:
from itertools import islice
def take(n, iterable):
"""Return the first n items of the iterable as a list."""
return list(islice(iterable, n))
See it working online: ideone
For Python < 3.6
n_items = take(n, d.iteritems())
A very efficient way to retrieve anything is to combine list or dictionary comprehensions with slicing. If you don't need to order the items (you just want n random pairs), you can use a dictionary comprehension like this:
# Python 2
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]}
# Python 3
first2pairs = {k: mydict[k] for k in list(mydict)[:2]}
Generally a comprehension like this is always faster to run than the equivalent "for x in y" loop. Also, by using .keys() to make a list of the dictionary keys and slicing that list you avoid 'touching' any unnecessary keys when you build the new dictionary.
If you don't need the keys (only the values) you can use a list comprehension:
first2vals = [v for v in mydict.values()[:2]]
If you need the values sorted based on their keys, it's not much more trouble:
first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]]
or if you need the keys as well:
first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]}
To get the top N elements from your python dictionary one can use the following line of code:
list(dictionaryName.items())[:N]
In your case you can change it to:
list(d.items())[:4]
Python's dicts are not ordered, so it's meaningless to ask for the "first N" keys.
The collections.OrderedDict class is available if that's what you need. You could efficiently get its first four elements as
import itertools
import collections
d = collections.OrderedDict((('foo', 'bar'), (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')))
x = itertools.islice(d.items(), 0, 4)
for key, value in x:
print key, value
itertools.islice allows you to lazily take a slice of elements from any iterator. If you want the result to be reusable you'd need to convert it to a list or something, like so:
x = list(itertools.islice(d.items(), 0, 4))
foo = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
iterator = iter(foo.items())
for i in range(3):
print(next(iterator))
Basically, turn the view (dict_items) into an iterator, and then iterate it with next().
in py3, this will do the trick
{A:N for (A,N) in [x for x in d.items()][:4]}
{'a': 3, 'b': 2, 'c': 3, 'd': 4}
You can get dictionary items by calling .items() on the dictionary. then convert that to a list and from there get first N items as you would on any list.
below code prints first 3 items of the dictionary object
e.g.
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
first_three_items = list(d.items())[:3]
print(first_three_items)
Outputs:
[('a', 3), ('b', 2), ('c', 3)]
For Python 3.8 the correct answer should be:
import more_itertools
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
first_n = more_itertools.take(3, d.items())
print(len(first_n))
print(first_n)
Whose output is:
3
[('a', 3), ('b', 2), ('c', 3)]
After pip install more-itertools of course.
Did not see it on here. Will not be ordered but the simplest syntactically if you need to just take some elements from a dictionary.
n = 2
{key:value for key,value in d.items()[0:n]}
Were d is your dictionary and n is the printing number:
for idx, (k, v) in enumerate(d.items()):
if idx == n: break
print(k, v)
Casting your dictionary to a list can be slow.
Your dictionary may be too large and you don't need to cast all of it just for printing a few of the first.
See PEP 0265 on sorting dictionaries. Then use the aforementioned iterable code.
If you need more efficiency in the sorted key-value pairs. Use a different data structure. That is, one that maintains sorted order and the key-value associations.
E.g.
import bisect
kvlist = [('a', 1), ('b', 2), ('c', 3), ('e', 5)]
bisect.insort_left(kvlist, ('d', 4))
print kvlist # [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
just add an answer using zip,
{k: d[k] for k, _ in zip(d, range(n))}
This will work for python 3.8+:
d_new = {k:v for i, (k, v) in enumerate(d.items()) if i < n}
This depends on what is 'most efficient' in your case.
If you just want a semi-random sample of a huge dictionary foo, use foo.iteritems() and take as many values from it as you need, it's a lazy operation that avoids creation of an explicit list of keys or items.
If you need to sort keys first, there's no way around using something like keys = foo.keys(); keys.sort() or sorted(foo.iterkeys()), you'll have to build an explicit list of keys. Then slice or iterate through first N keys.
BTW why do you care about the 'efficient' way? Did you profile your program? If you did not, use the obvious and easy to understand way first. Chances are it will do pretty well without becoming a bottleneck.
For Python 3 and above,To select first n Pairs
n=4
firstNpairs = {k: Diction[k] for k in list(Diction.keys())[:n]}
This might not be very elegant, but works for me:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
x= 0
for key, val in d.items():
if x == 2:
break
else:
x += 1
# Do something with the first two key-value pairs
You can approach this a number of ways. If order is important you can do this:
for key in sorted(d.keys()):
item = d.pop(key)
If order isn't a concern you can do this:
for i in range(4):
item = d.popitem()
Dictionary maintains no order , so before picking top N key value pairs lets make it sorted.
import operator
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
#itemgetter(0)=sort by keys, itemgetter(1)=sort by values
Now we can do the retrieval of top 'N' elements:, using the method structure like this:
def return_top(elements,dictionary_element):
'''Takes the dictionary and the 'N' elements needed in return
'''
topers={}
for h,i in enumerate(dictionary_element):
if h<elements:
topers.update({i:dictionary_element[i]})
return topers
to get the top 2 elements then simply use this structure:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
d=return_top(2,d)
print(d)
consider a dict
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
from itertools import islice
n = 3
list(islice(d.items(),n))
islice will do the trick :)
hope it helps !
I have tried a few of the answers above and note that some of them are version dependent and do not work in version 3.7.
I also note that since 3.6 all dictionaries are ordered by the sequence in which items are inserted.
Despite dictionaries being ordered since 3.6 some of the statements you expect to work with ordered structures don't seem to work.
The answer to the OP question that worked best for me.
itr = iter(dic.items())
lst = [next(itr) for i in range(3)]
def GetNFirstItems(self):
self.dict = {f'Item{i + 1}': round(uniform(20.40, 50.50), 2) for i in range(10)}#Example Dict
self.get_items = int(input())
for self.index,self.item in zip(range(len(self.dict)),self.dict.items()):
if self.index==self.get_items:
break
else:
print(self.item,",",end="")
Unusual approach, as it gives out intense O(N) time complexity.
I like this one because no new list needs to be created, its a one liner which does exactly what you want and it works with python >= 3.8 (where dictionaries are indeed ordered, I think from python 3.6 on?):
new_d = {kv[0]:kv[1] for i, kv in enumerate(d.items()) if i <= 4}

Categories