Recursive search JSON/DICT in Python 3 - python

I am realizing in Python 3 some APIs that allow me to receive information about a school based on the class code. But I would like to know how I get the information through the class code.
Example:
I enter the code GF528S and I want the program to tell me the class (3C INF), the address (Address 1, Milan), and if possible also the name of the school (Test School 1) and the previous keys. Thanks in advance! Of course I use a JSON structure:
{
"schools": {
"Lombardia": {
"Milano": {
"Milano": {
"Test School 1": {
"sedi": {
"0": {
"indirizzo": "Address 1, Milan",
"classi": {
"INFORMATICA E TELECOMUNICAZIONI": {
"3C INF": "GF528S"
}
}
},
"1": {
"indirizzo": "Address 2, Milan",
"classi": {
"INFORMATICA E TELECOMUNICAZIONI": {
"1A IT": "HKPV5P",
"2A IT": "QL3J3K",
"3A INF": "X4E35C",
"3A TEL": "ZAA7LC"
}
}
}
}
}
}
}
}
}
}
When I get the values ​​from my database they are converted to a python dictionary if it helps!
After a series of tests thanks to your answers, I found that the for in .items() is blocked when it shows the indirizzo field:
In particular, it cannot search in these dictionaries:
{'classi': {'INFORMATICA E TELECOMUNICAZIONI': {'3C INF': 'GF528S'}}, 'indirizzo': 'Address 1, Milan'}
{'classi': {'INFORMATICA E TELECOMUNICAZIONI': {'1A IT': 'HKPV5P', '2A IT': 'QL3J3K', '3A INF': 'X4E35C', '3A TEL': 'ZAA7LC'}}, 'indirizzo': 'Address 2, Milan'}
I think the problem is precisely the indirizzo field. If you want to do the for first, it can be saved in a variable and deleted from the json:
del val ["address"]
The problem is that then I can't associate the address with the class.
Code:
def dictionary_check(input):
indirizzo = ""
for key,value in input.items():
if isinstance(value, dict):
dictionary_check(value)
else:
for i in value:
indirizzo += i["indirizzo"]
del i['indirizzo']
for x, y in i.items():
for z, j in y.items():
for a in j.items():
if a[1] == "HKPV5P":
print(indirizzo)
print("Classe: " + a[0])

While I can't write the exact code for you, I think it's reasonable to be able to give you a rough idea of what the code would look like, and some guidance.
I don't exactly know where this JSON data is being obtained. So it may have more / less keys when your applications runs. However, assuming the json is exactly as is, and the json data is loaded onto the variable (let's say json_map), then accessing a specific value looks something like:
json_map[key_value]
So you would want to do something similar to
json_map['schools']['Lombardia']['Milano']
and more keys until you reach the dictionary you want to play around with.
I think the point you might be confused is - if you have multiple values (that you may not be aware of what they might look like) how you handle it. For example, I think the key "sedi" (which I assume means locations) might return multiple locations (i.e. schools) and you won't know what their keys / values are. In that case, you may wish to iterate through that dictionary via something like:
for key, value in dict_.items():
# do your action
it is likely that key will be an integer (in string format) and value will be another dictionary. You will want to check a specific attribute of the dictionary to see if it's the one you're looking for.
Also, finally, when you get to the 'INFORMATICA E TELECOMUNICAZIONI' dictionary of the location(s), you may wish to return the key of the item that has the corresponding value. Something like:
for key, value in dict_.items():
if value == 'GF528S':
return key
Of course, you'll be able to replace this value of 'GF528S' to a variable so you can change it each time.
I think this is as far as I can help you without actually implementing this. I gave the benefit of the doubt that you are like me when I just started programming and I just needed someone to give me a rough outline of what to do. Any more help, I think you may need grab someone who has knowledge of what to do IRL or hire a tutor/teacher to teach you basic concepts of Programming.

search_key = "GF528S"
def recursive_search(dct,keys):
for key,value in dct.items():
if key == search_key:
print(keys,value)
if type(value) == dict:
recursive_search(value,[*keys,key])
recursive_search(dinput_dict,[])

You should use recursive function to find key or value.
def search_key(data, key, path=""):
if type(data) is dict:
for k, v in data.items():
path="{0} -> {1}".format(path, k)
if k == key or v == key:
return (k, v, path)
res = search_key(data[k], key, path)
if res is not None:
return res
result = search_key(your_dictionary, key="GF528S")
if result is not None:
print("key:", result[0])
print("value:", result[1])
print("path:", result[2])
else:
print("key or value not found!")
If you want to search entire of dictionary and get all duplicate keys or values using given pattern key, this below function is useful.
def entire_search_key(data, key, founds=[], path=""):
if type(data) is dict:
for k, v in data.items():
path="{0} -> {1}".format(path, k)
if k == key or v == key:
founds.append((k, v, path))
entire_search_key(data[k], key, founds, path)
return founds
result = entire_search_key(your_dictionary, key="ddd")
if result == []:
print("key or value not found!")
else:
for i in result:
print(i)

Related

Python return key from value, but its a list in the dictionary

So Im quiet new to python and maybe I´ve searced the wrong words on google...
My current problem:
In python you can return the key to a value when its mentioned in a dictionary.
One thing I wonder, is it possible to return the key if the used value is part of a list of values to the key?
So my testing skript is the following
MainDict={'FAQ':['FAQ','faq','Faq']}
def key_return(X):
for Y, value in MainDict.items():
if X == value:
return Y
return "Key doesnt exist"
print(key_return(['FAQ', 'faq', 'Faq']))
print(key_return('faq'))
So I can just return the Key if I ask for the whole list,
How can I return the key if I just ask for one value of that list as written for the second print? On current code I get the "Key doesnt exist" as an answer.
You can check to see if a value in the dict is a list, and if it is check to see if the value you're searching for is in the list.
MainDict = {'FAQ':['FAQ','faq','Faq']}
def key_return(X):
for key, value in MainDict.items():
if X == value:
return key
if isinstance(value, list) and X in value:
return key
return "Key doesnt exist"
print(key_return(['FAQ', 'faq', 'Faq']))
print(key_return('faq'))
Note: You should also consider making MainDict a parameter that you pass to key_return instead of a global variable.
You can do this using next and a simple comprehension:
next(k for k, v in MainDict.items() if x == v or x in v)
So your code would look like:
MainDict = {'FAQ':['FAQ','faq','Faq']}
def key_return(x):
return next(k for k, v in MainDict.items() if x == v or x in v)
print(key_return(['FAQ', 'faq', 'Faq']))
#FAQ
print(key_return('faq'))
#FAQ
You can create a dict that maps from values in the lists to keys in MainDict:
MainDict={'FAQ':['FAQ','faq','Faq']}
back_dict = {value: k for k,values in MainDict.items() for value in values}
Then rewrite key_return to use this dict:
def key_return(X):
return back_dict[X]
print(key_return('faq'))
The line back_dict = {value: k for k,values in MainDict.items() for value in values} is a dictionary comprehension expression, which is equivalent to:
back_dict = {}
for k,values in MainDict.items():
for value in values:
back_dict[value] = k
This approach is more time-efficient that looping over every item of MainDict every time you search, since it only requires a single loopkup rather than a loop.

Remove the key value pairs based on value

a:{
b:{cd:"abc",
de:"rty"
},
c:{cd:"abc",
de:"uuy"
},
d:{cd:"ap",
de:"uy"
}
}
I want to print values of cd and de from this dictionary and if the value of cd is same then I only want to print once.
Expected output: b abc rty
d ap uy
How can I check if the value of cd is repeated or not ?
Edit :
hash_set=set()
hash_item=v1.get('query_hash',{}).get('sha256', "")
if hash_item in hash_set:
break
else:
hash_set.add(hash_item)
This is not working
How can I check if the value of cd is repeated or not ?
If you are iterating over stuff and you don't want to process duplicates keep a container of things you have already seen and skip items if they have been seen. sets are excellent containers for membership testing as the look-up is O(1) and sets don't allow duplicates.
Here is a toy example.
stuff = 'anjdusttnnssajd'
seen = set()
for thing in stuff:
if thing in seen:
continue
print(thing.upper()) # process thing
seen.add(thing)
Or you could just make a set of the things to process then process the things in the set.
stuff = set(stuff)
for thing in stuff:
print(thing.upper())
Using your criteria.
d = {'a':{'b':{'cd':"abc",'de':"rty"},
'c':{'cd':"abc",'de':"uuy"},
'd':{'cd':"ap",'de':"uy"}}}
seen = set()
for key,thing in d['a'].items():
cd,de = thing['cd'],thing['de']
if cd in seen:
continue
else:
print(key, cd, de)
seen.add(cd)
This code should help, I formated your JSON a little bit for it to be a valid python string but you should be able to modify it as you wish
def getKeys(dict):
return [*dict]
a = {
'b':{'cd':"abc",
'de':"rty"
},
'c':{'cd':"abc",
'de':"uuy"
},
'd':{'cd':"ap",
'de':"uy"
}
}
cd_list = []
keys = getKeys(a)
for key in keys:
found = False
for checked in cd_list:
if a[key]['cd']==checked:
found = True
break
if not found:
print( f'{key} : {a[key]["cd"]} {a[key]["de"]}')
cd_list.append(a[key]['cd'])
you can try this
dict={'a':{
'b':{'cd':"abc",
'de':"rty"
},
'c':{'cd':"abc",
'de':"uuy"
},
'd':{'cd':"ap",
'de':"uy"
}
}}
count=0
for key,item in dict.items():
for key,i in item.items():
if item['b']['cd']==i['cd']:
count=count+1
lis=i['cd']
else:
print(i['cd'])
if(count>1):
print(lis)
here is your code
data = {"a":{"b":{"cd":"abc","de":"rty"},"c":{"cd":"abc","de":"uuy"},"d":{"cd":"ap","de":"uy"}}}
output = set()
for key,val in data.items():
for key1,val1 in val.items():
for key2, val2 in val1.items():
if val2 not in output:
output.add(key1)
output.add(val2)
else:
break
print(output)

Elegant way to check if a nested key exists in a dict?

Is there are more readable way to check if a key buried in a dict exists without checking each level independently?
Lets say I need to get this value in a object buried (example taken from Wikidata):
x = s['mainsnak']['datavalue']['value']['numeric-id']
To make sure that this does not end with a runtime error it is necessary to either check every level like so:
if 'mainsnak' in s and 'datavalue' in s['mainsnak'] and 'value' in s['mainsnak']['datavalue'] and 'nurmeric-id' in s['mainsnak']['datavalue']['value']:
x = s['mainsnak']['datavalue']['value']['numeric-id']
The other way I can think of to solve this is wrap this into a try catch construct which I feel is also rather awkward for such a simple task.
I am looking for something like:
x = exists(s['mainsnak']['datavalue']['value']['numeric-id'])
which returns True if all levels exists.
To be brief, with Python you must trust it is easier to ask for forgiveness than permission
try:
x = s['mainsnak']['datavalue']['value']['numeric-id']
except KeyError:
pass
The answer
Here is how I deal with nested dict keys:
def keys_exists(element, *keys):
'''
Check if *keys (nested) exists in `element` (dict).
'''
if not isinstance(element, dict):
raise AttributeError('keys_exists() expects dict as first argument.')
if len(keys) == 0:
raise AttributeError('keys_exists() expects at least two arguments, one given.')
_element = element
for key in keys:
try:
_element = _element[key]
except KeyError:
return False
return True
Example:
data = {
"spam": {
"egg": {
"bacon": "Well..",
"sausages": "Spam egg sausages and spam",
"spam": "does not have much spam in it"
}
}
}
print 'spam (exists): {}'.format(keys_exists(data, "spam"))
print 'spam > bacon (do not exists): {}'.format(keys_exists(data, "spam", "bacon"))
print 'spam > egg (exists): {}'.format(keys_exists(data, "spam", "egg"))
print 'spam > egg > bacon (exists): {}'.format(keys_exists(data, "spam", "egg", "bacon"))
Output:
spam (exists): True
spam > bacon (do not exists): False
spam > egg (exists): True
spam > egg > bacon (exists): True
It loop in given element testing each key in given order.
I prefere this to all variable.get('key', {}) methods I found because it follows EAFP.
Function except to be called like: keys_exists(dict_element_to_test, 'key_level_0', 'key_level_1', 'key_level_n', ..). At least two arguments are required, the element and one key, but you can add how many keys you want.
If you need to use kind of map, you can do something like:
expected_keys = ['spam', 'egg', 'bacon']
keys_exists(data, *expected_keys)
You could use .get with defaults:
s.get('mainsnak', {}).get('datavalue', {}).get('value', {}).get('numeric-id')
but this is almost certainly less clear than using try/except.
Python 3.8 +
dictionary = {
"main_key": {
"sub_key": "value",
},
}
if sub_key_value := dictionary.get("main_key", {}).get("sub_key"):
print(f"The key 'sub_key' exists in dictionary[main_key] and it's value is {sub_key_value}")
else:
print("Key 'sub_key' doesn't exists or their value is Falsy")
Extra
A little but important clarification.
In the previous code block, we verify that a key exists in a dictionary but that its value is also Truthy.
Most of the time, this is what people are really looking for, and I think this is what the OP really wants. However, it is not really the most "correct" answer, since if the key exists but its value is False, the above code block will tell us that the key does not exist, which is not true.
So, I leet here a more correct answer:
dictionary = {
"main_key": {
"sub_key": False,
},
}
if "sub_key" in dictionary.get("main_key", {}):
print(f"The key 'sub_key' exists in dictionary[main_key] and it's value is {dictionary['main_key']['sub_key']}")
else:
print("Key 'sub_key' doesn't exists")
Try/except seems to be most pythonic way to do that.
The following recursive function should work (returns None if one of the keys was not found in the dict):
def exists(obj, chain):
_key = chain.pop(0)
if _key in obj:
return exists(obj[_key], chain) if chain else obj[_key]
myDict ={
'mainsnak': {
'datavalue': {
'value': {
'numeric-id': 1
}
}
}
}
result = exists(myDict, ['mainsnak', 'datavalue', 'value', 'numeric-id'])
print(result)
>>> 1
I suggest you to use python-benedict, a solid python dict subclass with full keypath support and many utility methods.
You just need to cast your existing dict:
s = benedict(s)
Now your dict has full keypath support and you can check if the key exists in the pythonic way, using the in operator:
if 'mainsnak.datavalue.value.numeric-id' in s:
# do stuff
Here the library repository and the documentation:
https://github.com/fabiocaccamo/python-benedict
Note: I am the author of this project
You can use pydash to check if exists: http://pydash.readthedocs.io/en/latest/api.html#pydash.objects.has
Or get the value (you can even set default - to return if doesn't exist): http://pydash.readthedocs.io/en/latest/api.html#pydash.objects.has
Here is an example:
>>> get({'a': {'b': {'c': [1, 2, 3, 4]}}}, 'a.b.c[1]')
2
The try/except way is the most clean, no contest. However, it also counts as an exception in my IDE, which halts execution while debugging.
Furthermore, I do not like using exceptions as in-method control statements, which is essentially what is happening with the try/catch.
Here is a short solution which does not use recursion, and supports a default value:
def chained_dict_lookup(lookup_dict, keys, default=None):
_current_level = lookup_dict
for key in keys:
if key in _current_level:
_current_level = _current_level[key]
else:
return default
return _current_level
The accepted answer is a good one, but here is another approach. It's a little less typing and a little easier on the eyes (in my opinion) if you end up having to do this a lot. It also doesn't require any additional package dependencies like some of the other answers. Have not compared performance.
import functools
def haskey(d, path):
try:
functools.reduce(lambda x, y: x[y], path.split("."), d)
return True
except KeyError:
return False
# Throwing in this approach for nested get for the heck of it...
def getkey(d, path, *default):
try:
return functools.reduce(lambda x, y: x[y], path.split("."), d)
except KeyError:
if default:
return default[0]
raise
Usage:
data = {
"spam": {
"egg": {
"bacon": "Well..",
"sausages": "Spam egg sausages and spam",
"spam": "does not have much spam in it",
}
}
}
(Pdb) haskey(data, "spam")
True
(Pdb) haskey(data, "spamw")
False
(Pdb) haskey(data, "spam.egg")
True
(Pdb) haskey(data, "spam.egg3")
False
(Pdb) haskey(data, "spam.egg.bacon")
True
Original inspiration from the answers to this question.
EDIT: a comment pointed out that this only works with string keys. A more generic approach would be to accept an iterable path param:
def haskey(d, path):
try:
functools.reduce(lambda x, y: x[y], path, d)
return True
except KeyError:
return False
(Pdb) haskey(data, ["spam", "egg"])
True
I had the same problem and recent python lib popped up:
https://pypi.org/project/dictor/
https://github.com/perfecto25/dictor
So in your case:
from dictor import dictor
x = dictor(s, 'mainsnak.datavalue.value.numeric-id')
Personal note:
I don't like 'dictor' name, since it doesn't hint what it actually does. So I'm using it like:
from dictor import dictor as extract
x = extract(s, 'mainsnak.datavalue.value.numeric-id')
Couldn't come up with better naming than extract. Feel free to comment, if you come up with more viable naming. safe_get, robust_get didn't felt right for my case.
Another way:
def does_nested_key_exists(dictionary, nested_key):
exists = nested_key in dictionary
if not exists:
for key, value in dictionary.items():
if isinstance(value, dict):
exists = exists or does_nested_key_exists(value, nested_key)
return exists
The selected answer works well on the happy path, but there are a couple obvious issues to me. If you were to search for ["spam", "egg", "bacon", "pizza"], it would throw a type error due to trying to index "well..." using the string "pizza". Like wise, if you replaced pizza with 2, it would use that to get the index 2 from "Well..."
Selected Answer Output Issues:
data = {
"spam": {
"egg": {
"bacon": "Well..",
"sausages": "Spam egg sausages and spam",
"spam": "does not have much spam in it"
}
}
}
print(keys_exists(data, "spam", "egg", "bacon", "pizza"))
>> TypeError: string indices must be integers
print(keys_exists(data, "spam", "egg", "bacon", 2)))
>> l
I also feel that using try except can be a crutch that we might too quickly rely on. Since I believe we already need to check for the type, might as well remove the try except.
Solution:
def dict_value_or_default(element, keys=[], default=Undefined):
'''
Check if keys (nested) exists in `element` (dict).
Returns value if last key exists, else returns default value
'''
if not isinstance(element, dict):
return default
_element = element
for key in keys:
# Necessary to ensure _element is not a different indexable type (list, string, etc).
# get() would have the same issue if that method name was implemented by a different object
if not isinstance(_element, dict) or key not in _element:
return default
_element = _element[key]
return _element
Output:
print(dict_value_or_default(data, ["spam", "egg", "bacon", "pizza"]))
>> INVALID
print(dict_value_or_default(data, ["spam", "egg", "bacon", 2]))
>> INVALID
print(dict_value_or_default(data, ["spam", "egg", "bacon"]))
>> "Well..."
Here's my small snippet based on #Aroust's answer:
def exist(obj, *keys: str) -> bool:
_obj = obj
try:
for key in keys:
_obj = _obj[key]
except (KeyError, TypeError):
return False
return True
if __name__ == '__main__':
obj = {"mainsnak": {"datavalue": {"value": "A"}}}
answer = exist(obj, "mainsnak", "datavalue", "value", "B")
print(answer)
I added TypeError because when _obj is str, int, None, or etc, it would raise that error.
I wrote a data parsing library called dataknead for cases like this, basically because i got frustrated by the JSON the Wikidata API returns as well.
With that library you could do something like this
from dataknead import Knead
numid = Knead(s).query("mainsnak/datavalue/value/numeric-id").data()
if numid:
# Do something with `numeric-id`
Using dict with defaults is concise and appears to execute faster than using consecutive if statements.
Try it yourself:
import timeit
timeit.timeit("'x' in {'a': {'x': {'y'}}}.get('a', {})")
# 0.2874350370002503
timeit.timeit("'a' in {'a': {'x': {'y'}}} and 'x' in {'a': {'x': {'y'}}}['a']")
# 0.3466246419993695
I have written a handy library for this purpose.
I am iterating over ast of the dict and trying to check if a particular key is present or not.
Do check this out.
https://github.com/Agent-Hellboy/trace-dkey
If you can suffer testing a string representation of the object path then this approach might work for you:
def exists(str):
try:
eval(str)
return True
except:
return False
exists("lst['sublist']['item']")
one can try to use this for checking whether key/nestedkey/value is in nested dict
import yaml
#d - nested dictionary
if something in yaml.dump(d, default_flow_style=False):
print(something, "is in", d)
else:
print(something, "is not in", d)
There are many great answers. here is my humble take on it. Added check for array of dictionaries as well. Please note that I am not checking for arguments validity. I used part Arnot's code above. I added this answer because a I got a use case that requires checking array or dictionaries in my data.
Here is the code:
def keys_exists(element, *keys):
'''
Check if *keys (nested) exists in `element` (dict).
'''
retval=False
if isinstance(element,dict):
for key,value in element.items():
for akey in keys:
if element.get(akey) is not None:
return True
if isinstance(value,dict) or isinstance(value,list):
retval= keys_exists(value, *keys)
elif isinstance(element, list):
for val in element:
if isinstance(val,dict) or isinstance(val,list):
retval=keys_exists(val, *keys)
return retval

How to make my code more simple using python

this is my code:
def set_floor_point(self,floor_point=None):
if self.data.get('stage'):
self.data['stage'] = {}
stage_number = self.get_stage_number()
floor_number = self.get_floor_number()
if self.data['stage'].get(stage_number):
self.data['stage'][stage_number] = {}
if self.data['stage'][stage_number].get('floor_point'):
self.data['stage'][stage_number]['floor_point'] = {}
if self.data['stage'][stage_number]['floor_point'].get(floor_number):
self.data['stage'][stage_number]['floor_point'][floor_number] = {}
self.data['stage'][stage_number]['floor_point'][floor_number] = floor_point
and the dict i create when first time is like this :
stage =
{
0:{
'floor':{
0:{
'floor_point':0,
'gift':{}
}
}
}
}
but i think my code is not very good , it is too Cumbersome,
so Are someone know more simple way ,
thanks
data = collections.defaultdict(lambda: collections.defaultdict(
lambda: collections.defaultdict(dict)))
data['stage'][3]['floor_point'][2] = 5
print data
I'm not sure what you want to achieve. A recurring theme in your code is:
if some_dict.get(key):
some_dict[key] = {}
That means: if some_dict has a key key and some_dict[key] is a truthy value, then replace some_dict[key] by {}. If some_dict doesn't have a key key or some_dict[key] is a falsy value (None, 0, False, [] etc.), then do nothing.
If that is what you wanted, you could clarify your like this:
def replace_value_by_empty_dict(d, key):
if d.get(key):
d[key] = {}
...
replace_value_by_empty_dict(self.data, 'stage')
etc.
But if that's not what you intended (the code will break if one of the ifs is true), you might want to phrase the problem in english words or pseudocode to clarify the structure of the problem.
And have a look at collections.defaultdict.

Finding matching keys in two large dictionaries and doing it fast

I am trying to find corresponding keys in two different dictionaries. Each has about 600k entries.
Say for example:
myRDP = { 'Actinobacter': 'GATCGA...TCA', 'subtilus sp.': 'ATCGATT...ACT' }
myNames = { 'Actinobacter': '8924342' }
I want to print out the value for Actinobacter (8924342) since it matches a value in myRDP.
The following code works, but is very slow:
for key in myRDP:
for jey in myNames:
if key == jey:
print key, myNames[key]
I've tried the following but it always results in a KeyError:
for key in myRDP:
print myNames[key]
Is there perhaps a function implemented in C for doing this? I've googled around but nothing seems to work.
Thanks.
Use sets, because they have a built-in intersection method which ought to be quick:
myRDP = { 'Actinobacter': 'GATCGA...TCA', 'subtilus sp.': 'ATCGATT...ACT' }
myNames = { 'Actinobacter': '8924342' }
rdpSet = set(myRDP)
namesSet = set(myNames)
for name in rdpSet.intersection(namesSet):
print name, myNames[name]
# Prints: Actinobacter 8924342
You could do this:
for key in myRDP:
if key in myNames:
print key, myNames[key]
Your first attempt was slow because you were comparing every key in myRDP with every key in myNames. In algorithmic jargon, if myRDP has n elements and myNames has m elements, then that algorithm would take O(n×m) operations. For 600k elements each, this is 360,000,000,000 comparisons!
But testing whether a particular element is a key of a dictionary is fast -- in fact, this is one of the defining characteristics of dictionaries. In algorithmic terms, the key in dict test is O(1), or constant-time. So my algorithm will take O(n) time, which is one 600,000th of the time.
in python 3 you can just do
myNames.keys() & myRDP.keys()
for key in myRDP:
name = myNames.get(key, None)
if name:
print key, name
dict.get returns the default value you give it (in this case, None) if the key doesn't exist.
You could start by finding the common keys and then iterating over them. Set operations should be fast because they are implemented in C, at least in modern versions of Python.
common_keys = set(myRDP).intersection(myNames)
for key in common_keys:
print key, myNames[key]
Best and easiest way would be simply perform common set operations(Python 3).
a = {"a": 1, "b":2, "c":3, "d":4}
b = {"t1": 1, "b":2, "e":5, "c":3}
res = a.items() & b.items() # {('b', 2), ('c', 3)} For common Key and Value
res = {i[0]:i[1] for i in res} # In dict format
common_keys = a.keys() & b.keys() # {'b', 'c'}
Cheers!
Use the get method instead:
for key in myRDP:
value = myNames.get(key)
if value != None:
print key, "=", value
You can simply write this code and it will save the common key in a list.
common = [i for i in myRDP.keys() if i in myNames.keys()]
Copy both dictionaries into one dictionary/array. This makes sense as you have 1:1 related values. Then you need only one search, no comparison loop, and can access the related value directly.
Example Resulting Dictionary/Array:
[Name][Value1][Value2]
[Actinobacter][GATCGA...TCA][8924342]
[XYZbacter][BCABCA...ABC][43594344]
...
Here is my code for doing intersections, unions, differences, and other set operations on dictionaries:
class DictDiffer(object):
"""
Calculate the difference between two dictionaries as:
(1) items added
(2) items removed
(3) keys same in both but changed values
(4) keys same in both and unchanged values
"""
def __init__(self, current_dict, past_dict):
self.current_dict, self.past_dict = current_dict, past_dict
self.set_current, self.set_past = set(current_dict.keys()), set(past_dict.keys())
self.intersect = self.set_current.intersection(self.set_past)
def added(self):
return self.set_current - self.intersect
def removed(self):
return self.set_past - self.intersect
def changed(self):
return set(o for o in self.intersect if self.past_dict[o] != self.current_dict[o])
def unchanged(self):
return set(o for o in self.intersect if self.past_dict[o] == self.current_dict[o])
if __name__ == '__main__':
import unittest
class TestDictDifferNoChanged(unittest.TestCase):
def setUp(self):
self.past = dict((k, 2*k) for k in range(5))
self.current = dict((k, 2*k) for k in range(3,8))
self.d = DictDiffer(self.current, self.past)
def testAdded(self):
self.assertEqual(self.d.added(), set((5,6,7)))
def testRemoved(self):
self.assertEqual(self.d.removed(), set((0,1,2)))
def testChanged(self):
self.assertEqual(self.d.changed(), set())
def testUnchanged(self):
self.assertEqual(self.d.unchanged(), set((3,4)))
class TestDictDifferNoCUnchanged(unittest.TestCase):
def setUp(self):
self.past = dict((k, 2*k) for k in range(5))
self.current = dict((k, 2*k+1) for k in range(3,8))
self.d = DictDiffer(self.current, self.past)
def testAdded(self):
self.assertEqual(self.d.added(), set((5,6,7)))
def testRemoved(self):
self.assertEqual(self.d.removed(), set((0,1,2)))
def testChanged(self):
self.assertEqual(self.d.changed(), set((3,4)))
def testUnchanged(self):
self.assertEqual(self.d.unchanged(), set())
unittest.main()
def combine_two_json(json_request, json_request2):
intersect = {}
for item in json_request.keys():
if item in json_request2.keys():
intersect[item]=json_request2.get(item)
return intersect

Categories

Resources