I have an output (a list) of items, like such:
Root
Branch1
LeafA
LeafB
Branch2
LeafC
LeafZ
LeafD
They are all two-space delimited.
I want build a logical representation of this list without the leading spaces, and retain the parent-child relationshiop.
A final possible result:
aDict = {
'Root': null,
'Branch1': 'Root',
'LeafA': 'Branch1',
... so on and so forth
}
Ultimately, I want to iterate through the dictionary and retrieve the Key and parent, as well as another value from another dict based on Key.
Try this:
tree = """Root
Branch1
LeafA
LeafB
Branch2
LeafC
LeafZ
LeafD"""
aDict = {}
iDict = {}
for line in tree.split("\n"):
key = line.lstrip(" ")
indent = (len(line) - len(key)) / 2
if indent == 0:
aDict[key] = None
else:
aDict[key] = iDict[indent - 1]
iDict[indent] = key
print aDict
# {'LeafD': 'Branch2', 'LeafA': 'Branch1', 'Branch2': 'Root', 'LeafC': 'Branch2', 'LeafB': 'Branch1', 'Branch1': 'Root', 'Root': None, 'LeafZ': 'LeafC'}
I guess this solves the problem:
#!/usr/bin/env python
def f(txt):
stack = []
ret = {}
for line in txt.split('\n'):
a = line.split(' ')
level = len(a) - 1
key = a[-1]
stack = stack[:level]
ret[key] = stack[-1] if len(stack) > 0 else None
stack.append(key)
return ret
print f("""Root
Branch1
LeafA
LeafB
Branch2
LeafC
LeafZ
LeafD""")
print f("""Root1
Branch1
LeafA
LeftZ
Branch2
LeftB
Root2
Branch3""")
Output:
{'LeafD': 'Branch2', 'LeafA': 'Branch1', 'Branch2': 'Root', 'LeafC': 'Branch2', 'LeafB': 'Branch1', 'Branch1': 'Root', 'Root': None, 'LeafZ': 'LeafC'}
{'LeafA': 'Branch1', 'Branch2': 'Root1', 'Branch1': 'Root1', 'LeftZ': 'LeafA', 'LeftB': 'Branch2', 'Branch3': 'Root2', 'Root1': None, 'Root2': None}
Related
here is the mindmap
and corresponding csv file is
history,Africa,Egyptian,pyramid
,Asia,Ancient India,Caste System
,,,Buddhism
,Eourp,Greece,xxx
,,Rome,yyy
,,,zzzz
I want to convert csv file to json like struct
{
'history': [
{
'Africa': [
{
'Egyptian': [{'pyramid': []}]
}
]
},
{
'Asia': [
{
'Ancient India': [
{'Caste System': []},
{'Buddhism': []}
]
}
]
},
...
]
}
finally a function to find the key and print the path of that key
e.g. find('Buddhism') -> history.Asia.Ancient India.Buddhism
I've tried Tree but I have no idea how to achieve this.
Here's a working solution:
# Load your string into list of list
m = []
for each in s.split('\n'):
l = each.split(',')
m.append(l)
# Create dict object that you want.
master = {}
level_indexes = [-1]*10
for i in range(len(m)):
level = len([e for e in m[i] if e == ''])
level_indexes[level] = i
level_indexes[level+1:] = [-1]*(10-level-1)
if level == 0:
head = master
for each in m[i]:
head[each] = {}
head = head[each]
else:
head = master
indexes = []
for j, e in enumerate(level_indexes[:level]):
if e is not -1:
indexes.append(j)
indexes.append(level)
last = []
for j in range(len(indexes)-1):
last.extend(m[level_indexes[j]][indexes[j]:indexes[j+1]])
for j in range(level):
head = head[last[j]]
for j in range(level, len(m[i])):
head[m[i][j]] = {}
head = head[m[i][j]]
This creates a nested dictionary - master:
{'history': {'Africa': {'Egyptian': {'pyramid': {}}},
'Asia': {'Ancient India': {'Buddhism': {}, 'Caste System': {}}},
'Eourp': {'Greece': {'xxx': {}},
'Rome': {'yyy': {}, 'zzzz': {}}}}}
If you tweak it a little bit, you can put everything in list, but that will make it much more complicated:
master = []
level_indexes = [-1]*10
for i in range(len(m)):
level = len([e for e in m[i] if e == ''])
level_indexes[level] = i
level_indexes[level+1:] = [-1]*(10-level-1)
if level == 0:
head = master
for each in m[i]:
head.append({each: []})
head = head[-1][each]
else:
head = master
indexes = []
for j, e in enumerate(level_indexes[:level]):
if e is not -1:
indexes.append(j)
indexes.append(level)
last = []
for j in range(len(indexes)-1):
last.extend(m[level_indexes[j]][indexes[j]:indexes[j+1]])
for j in range(level):
head = head[-1][last[j]]
for j in range(level, len(m[i])):
head.append({m[i][j]: []})
head = head[-1][m[i][j]]
output:
[{'history': [{'Africa': [{'Egyptian': [{'pyramid': []}]}]},
{'Asia': [{'Ancient India': [{'Caste System': []},
{'Buddhism': []}]}]},
{'Eourp': [{'Greece': [{'xxx': []}]},
{'Rome': [{'yyy': []}, {'zzzz': []}]}]}]}]
How to print either 1 specific value, or a select key2 values for all key1 from a nested dictionary? The lines in my code display nothing.
Foe example, how to print (a single value):
Canon-PS-G7-X-Mark-II`
or (select key2 values for all key1):
Canon-PS-G7-X-Mark-II
Nikon-D5
Sony-alpha9
The dictionary (part of it) and code
config = {
'g7': {},
'd5': {},
'a9': {},
}
config['g7']['cam_name'] = ('Canon-PS-G7-X-Mark-II')
config['d5']['cam_name'] = ('Nikon-D5')
config['a9']['cam_name'] = ('Sony-alpha9')
camtype = """
1 camera:
(config['g7']['cam_name'])
all cameras
(config[.]['cam_name'])
"""
print(camtype)
try below code:
config = {
'g7': {},
'd5': {},
'a9': {},
}
config['g7']['cam_name'] = ('Canon-PS-G7-X-Mark-II')
config['d5']['cam_name'] = ('Nikon-D5')
config['a9']['cam_name'] = ('Sony-alpha9')
camtype = """
1 camera:
({0})
all cameras
({1})
"""
single_camera = config['g7']['cam_name']
all_camera = ', '.join([config[k]['cam_name'] for k in config])
print(camtype.format(single_camera, all_camera))
output:
1 camera:
(Canon-PS-G7-X-Mark-II)
all cameras
(['Canon-PS-G7-X-Mark-II', 'Nikon-D5', 'Sony-alpha9'])
I am sure someone else can do better than I.
config = {
'g7': {},
'd5': {},
'a9': {},
}
config['g7']['cam_name'] = ('Canon-PS-G7-X-Mark-II')
config['d5']['cam_name'] = ('Nikon-D5')
config['a9']['cam_name'] = ('Sony-alpha9')
camtype = """1 camera: %s""" %(config['g7']['cam_name']) #search up python print function
allcam = [ value['cam_name'] for key, value in config.items()] #creates list with all cameras
str_allcam = "all cameras " + ', '.join( str(p) for p in allcam) # prints all cameras with a comma seperator
print(camtype +"\n" + str_allcam) # outputs a two lines because of newline seperator
Say I have a file with the following:
/* Full name: abc */
.....
.....(.....)
.....(".....) ;
/* .....
/* .....
..... : "....."
}
"....., .....
Car : true ;
House : true ;
....
....
Age : 33
....
/* Full name: xyz */
....
....
Car : true ;
....
....
Age : 56
....
I am only interested in full name, car, house and age of each person. There are many other lines of data with different format between the variable/attritbute that I am interested.
My code so far:
import re
initial_val = {'House': 'false', 'Car': 'false'}
with open('input.txt') as f:
records = []
current_record = None
for line in f:
if not line.strip():
continue
elif current_record is None:
people_name = re.search('.+Full name ?: (.+) ', line)
if people_name:
current_record = dict(initial_val, Name = people_name.group(1))
else:
continue
elif current_record is not None:
house = re.search(' *(House) ?: ?([a-z]+)', line)
if house:
current_record['House'] = house.group(2)
car = re.search(' *(Car) ?: ?([a-z]+)', line)
if car:
current_record['Car'] = car.group(2)
people_name = re.search('.+Full name ?: (.+) ', line)
if people_name:
records.append(current_record)
current_record = dict(initial_val, Name = people_name.group(1))
print records
What I get:
[{'Name': 'abc', 'House': 'true', 'Car': 'true'}]
My question:
How am I suppose to extract the data and store it in a dictionary like:
{'abc': {'Car': true, 'House': true, 'Age': 33}, 'xyz':{'Car': true, 'House': false, 'Age': 56}}
My purpose:
check whether each person has car, house and age, if no then return false
The I could print them in a table like this:
Name Car House Age
abc true true 33
xyz true false 56
Note that I am using Python 2.7 and I do not know what is the actual value of each variable/attribute (Eg. abc, true, true, 33) of each person.
What is the best solution to my question? Thanks.
Well, you just have to keep track of the current record:
def parse_name(line):
# first remove the initial '/* ' and final ' */'
stripped_line = line.strip('/* ')
return stripped_line.split(':')[-1]
WANTED_KEYS = ('Car', 'Age', 'House')
# default values for when the lines are not present for a record
INITIAL_VAL = {'Car': False, 'House': False, Age: -1}
with open('the_filename') as f:
records = []
current_record = None
for line in f:
if not line.strip():
# skip empty lines
continue
elif current_record is None:
# first record in the file
if line.startswith('/*'):
current_record = dict(INITIAL_VAL, name=parse_name(line))
else:
# this should probably be an error in the file contents
continue
elif line.startswith('/*'):
# this means that the current record finished, and a new one is starting
records.append(current_record)
current_record = dict(INITIAL_VAL, name=parse_name(line))
else:
key, val = line.split(':')
if key.strip() in WANTED_KEYS:
# we want to keep track of this field
current_record[key.strip()] = val.strip()
# otherwise just ignore the line
print('Name\tCar\tHouse\tAge')
for record in records:
print(record['name'], record['Car'], record['House'], record['Age'], sep='\t')
Note that for Age you may want to convert it to an integer using int:
if key == 'Age':
current_record['Age'] = int(val)
The above code produces a list of dictionaries, but it is easy enough to convert it to a dictionary of dicts:
new_records = {r['name']: dict(r) for r in records}
for val in new_records.values():
del val['name']
After this new_records will be something like:
{'abc': {'Car': True, 'House': True, Age: 20}, ...}
If you have other lines with a different format in between the interesting ones you can simply write a function that returns True or False depending on whether the line is in the format you require and use it to filter the lines of the file:
def is_interesting_line(line):
if line.startswith('/*'):
return True
elif ':' in line:
return True
for line in filter(is_interesting_line, f):
# code as before
Change is_interesting_line to suit your needs. In the end, if you have to handle several different formats etc. maybe using a regex would be better, in that case you could do something like:
import re
LINE_REGEX = re.compile(r'(/\*.*\*/)|(\w+\s*:.*)| <other stuff>')
def is_interesting_line(line):
return LINE_REGEX.match(line) is not None
If you want you can obtain fancier formatting for the table, but you probably first need to determine the maximum length of the name etc. or you can use something like tabulate to do that for you.
For example something like (not tested):
max_name_length = max(max(len(r['name']) for r in records), 4)
format_string = '{:<{}}\t{:<{}}\t{}\t{}'
print(format_string.format('Name', max_name_length, 'Car', 5, 'House', 'Age'))
for record in records:
print(format_string.format(record['name'], max_name_length, record['Car'], 5, record['House'], record['Age']))
I need to convert logical data dictionary to a physical (abbreviated) data dictionary - I have given 4 use cases below.
Need help for this psuedo-code / requirement:
# empty dict declaration
refDict = {}
# to catch and report on any 'not-found' dictionary words to replace
noMatchFound = {}
# read from a dictionary of comma delimited dictionary
# with open('dictionary.csv') as inputDict:
# for line in inputDict:
# busTerm, busAbbr = line.split(',')
# refDict[busTerm] = busAbbr.replace("\n","")
# sample data dictionary entries
refDict = {
'user': 'USR',
'call': 'CALL',
'detail': 'DTL',
'record': 'REC',
'call detail record': 'CDR',
'count', 'CNT'}
input_string1="user call detail record"
# output should be "USR_CDR"
# noMatchFound - will be empty - since all are matched and replaced
input_string2="user test call detail record"
# output should be "USR_TEST_CDR"
# noMatchFound - should have an entry "TEST" with a refernce to "user test call detail record"
input_string3="user call count detail record"
# output should be "USR_CALL_CNT_DTL_REC"
# noMatchFound - will be empty - since all are matched and replaced
input_string4="user call detail record count"
# output should be "USR_CDR_CNT"
# noMatchFound - will be empty - since all are matched and replaced
So far, I could figure out the code snippet for matching any possible one-single-largest-expression as:
import re
# using regular expressions find longest matcing expression
def getLongestSequenceSize(inputStr, inDict):
ret_match = ""
ret_match_len = 0
ret_abbr = ""
for inKey in inDict:
matches = re.findall(r'(?:\b%s\b\s?)+' % inKey.strip().upper(), inputStr.strip().upper())
if len(matches) > 0:
longest_match = max(matches)
if ret_match_len < len(longest_match):
ret_match_len = len(longest_match)
ret_match = longest_match.strip()
ret_abbr = inDict[inKey]
return [ret_match.strip(), ret_abbr.strip()]
The idea is you start trying to replace() from the biggest string in the dictionary and you check every possible replacement given the dictionary, from longer to shorter.
This exactly works as you expected:
refDict = {
'user': 'USR',
'call': 'CALL',
'detail': 'DTL',
'record': 'REC',
'call detail record': 'CDR',
'count': 'CNT'}
sorted_ref = sorted( refDict.items(), key=lambda x:len(x[0]), reverse = True )
def do_work(input_string):
noMatchFound = {}
rval = input_string[:]
for key, value in sorted_ref:
rval = rval.replace(key, value)
not_founds = [x for x in rval.split() if x.islower()]
for not_found in not_founds:
noMatchFound[not_found] = input_string
rval = rval.replace(not_found, not_found.upper())
rval = '_'.join( rval.split() )
return rval, noMatchFound
inputs = ["user call detail record", "user test call detail record",
"user call count detail record","user call detail record count"]
for inp in inputs:
print inp
output, noMatchFound = do_work(inp)
print output
print noMatchFound
print '---'
Output:
user call detail record
USR_CDR
{}
---
user test call detail record
USR_TEST_CDR
{'test': 'user test call detail record'}
---
user call count detail record
USR_CALL_CNT_DTL_REC
{}
---
user call detail record count
USR_CDR_CNT
{}
Search for a value and get the parent dictionary names (keys):
Dictionary = {dict1:{
'part1': {
'.wbxml': 'application/vnd.wap.wbxml',
'.rl': 'application/resource-lists+xml',
},
'part2':
{'.wsdl': 'application/wsdl+xml',
'.rs': 'application/rls-services+xml',
'.xop': 'application/xop+xml',
'.svg': 'image/svg+xml',
},
'part3':{...}, ...
dict2:{
'part1': { '.dotx': 'application/vnd.openxmlformats-..'
'.zaz': 'application/vnd.zzazz.deck+xml',
'.xer': 'application/patch-ops-error+xml',}
},
'part2':{...},
'part3':{...},...
},...
In above dictionary I need to search values like: "image/svg+xml". Where, none of the values are repeated in the dictionary. How to search the "image/svg+xml"? so that it should return the parent keys in a dictionary { dict1:"part2" }.
Please note: Solutions should work unmodified for both Python 2.7 and Python 3.3.
Here's a simple recursive version:
def getpath(nested_dict, value, prepath=()):
for k, v in nested_dict.items():
path = prepath + (k,)
if v == value: # found value
return path
elif hasattr(v, 'items'): # v is a dict
p = getpath(v, value, path) # recursive call
if p is not None:
return p
Example:
print(getpath(dictionary, 'image/svg+xml'))
# -> ('dict1', 'part2', '.svg')
To yield multiple paths (Python 3 only solution):
def find_paths(nested_dict, value, prepath=()):
for k, v in nested_dict.items():
path = prepath + (k,)
if v == value: # found value
yield path
elif hasattr(v, 'items'): # v is a dict
yield from find_paths(v, value, path)
print(*find_paths(dictionary, 'image/svg+xml'))
This is an iterative traversal of your nested dicts that additionally keeps track of all the keys leading up to a particular point. Therefore as soon as you find the correct value inside your dicts, you also already have the keys needed to get to that value.
The code below will run as-is if you put it in a .py file. The find_mime_type(...) function returns the sequence of keys that will get you from the original dictionary to the value you want. The demo() function shows how to use it.
d = {'dict1':
{'part1':
{'.wbxml': 'application/vnd.wap.wbxml',
'.rl': 'application/resource-lists+xml'},
'part2':
{'.wsdl': 'application/wsdl+xml',
'.rs': 'application/rls-services+xml',
'.xop': 'application/xop+xml',
'.svg': 'image/svg+xml'}},
'dict2':
{'part1':
{'.dotx': 'application/vnd.openxmlformats-..',
'.zaz': 'application/vnd.zzazz.deck+xml',
'.xer': 'application/patch-ops-error+xml'}}}
def demo():
mime_type = 'image/svg+xml'
try:
key_chain = find_mime_type(d, mime_type)
except KeyError:
print ('Could not find this mime type: {0}'.format(mime_type))
exit()
print ('Found {0} mime type here: {1}'.format(mime_type, key_chain))
nested = d
for key in key_chain:
nested = nested[key]
print ('Confirmation lookup: {0}'.format(nested))
def find_mime_type(d, mime_type):
reverse_linked_q = list()
reverse_linked_q.append((list(), d))
while reverse_linked_q:
this_key_chain, this_v = reverse_linked_q.pop()
# finish search if found the mime type
if this_v == mime_type:
return this_key_chain
# not found. keep searching
# queue dicts for checking / ignore anything that's not a dict
try:
items = this_v.items()
except AttributeError:
continue # this was not a nested dict. ignore it
for k, v in items:
reverse_linked_q.append((this_key_chain + [k], v))
# if we haven't returned by this point, we've exhausted all the contents
raise KeyError
if __name__ == '__main__':
demo()
Output:
Found image/svg+xml mime type here: ['dict1', 'part2', '.svg']
Confirmation lookup: image/svg+xml
Here is a solution that works for a complex data structure of nested lists and dicts
import pprint
def search(d, search_pattern, prev_datapoint_path=''):
output = []
current_datapoint = d
current_datapoint_path = prev_datapoint_path
if type(current_datapoint) is dict:
for dkey in current_datapoint:
if search_pattern in str(dkey):
c = current_datapoint_path
c+="['"+dkey+"']"
output.append(c)
c = current_datapoint_path
c+="['"+dkey+"']"
for i in search(current_datapoint[dkey], search_pattern, c):
output.append(i)
elif type(current_datapoint) is list:
for i in range(0, len(current_datapoint)):
if search_pattern in str(i):
c = current_datapoint_path
c += "[" + str(i) + "]"
output.append(i)
c = current_datapoint_path
c+="["+ str(i) +"]"
for i in search(current_datapoint[i], search_pattern, c):
output.append(i)
elif search_pattern in str(current_datapoint):
c = current_datapoint_path
output.append(c)
output = filter(None, output)
return list(output)
if __name__ == "__main__":
d = {'dict1':
{'part1':
{'.wbxml': 'application/vnd.wap.wbxml',
'.rl': 'application/resource-lists+xml'},
'part2':
{'.wsdl': 'application/wsdl+xml',
'.rs': 'application/rls-services+xml',
'.xop': 'application/xop+xml',
'.svg': 'image/svg+xml'}},
'dict2':
{'part1':
{'.dotx': 'application/vnd.openxmlformats-..',
'.zaz': 'application/vnd.zzazz.deck+xml',
'.xer': 'application/patch-ops-error+xml'}}}
d2 = {
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{"id": "1001", "type": "Regular"},
{"id": "1002", "type": "Chocolate"},
{"id": "1003", "type": "Blueberry"},
{"id": "1004", "type": "Devil's Food"}
]
},
"topping":
[
{"id": "5001", "type": "None"},
{"id": "5002", "type": "Glazed"},
{"id": "5005", "type": "Sugar"},
{"id": "5007", "type": "Powdered Sugar"},
{"id": "5006", "type": "Chocolate with Sprinkles"},
{"id": "5003", "type": "Chocolate"},
{"id": "5004", "type": "Maple"}
]
},
...
]
}
}
pprint.pprint(search(d,'svg+xml','d'))
>> ["d['dict1']['part2']['.svg']"]
pprint.pprint(search(d2,'500','d2'))
>> ["d2['items']['item'][0]['topping'][0]['id']",
"d2['items']['item'][0]['topping'][1]['id']",
"d2['items']['item'][0]['topping'][2]['id']",
"d2['items']['item'][0]['topping'][3]['id']",
"d2['items']['item'][0]['topping'][4]['id']",
"d2['items']['item'][0]['topping'][5]['id']",
"d2['items']['item'][0]['topping'][6]['id']"]
Here are two similar quick and dirty ways of doing this type of operation. The function find_parent_dict1 uses list comprehension but if you are uncomfortable with that then find_parent_dict2 uses the infamous nested for loops.
Dictionary = {'dict1':{'part1':{'.wbxml':'1','.rl':'2'},'part2':{'.wbdl':'3','.rs':'4'}},'dict2':{'part3':{'.wbxml':'5','.rl':'6'},'part4':{'.wbdl':'1','.rs':'10'}}}
value = '3'
def find_parent_dict1(Dictionary):
for key1 in Dictionary.keys():
item = {key1:key2 for key2 in Dictionary[key1].keys() if value in Dictionary[key1][key2].values()}
if len(item)>0:
return item
find_parent_dict1(Dictionary)
def find_parent_dict2(Dictionary):
for key1 in Dictionary.keys():
for key2 in Dictionary[key1].keys():
if value in Dictionary[key1][key2].values():
print {key1:key2}
find_parent_dict2(Dictionary)
Traverses a nested dict looking for a particular value. When success is achieved the full key path to the value is printed. I left all the comments and print statements for pedagogical purposes (this isn't production code!)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 24 17:16:46 2022
#author: wellington
"""
class Tree(dict):
"""
allows autovivification as in Perl hashes
"""
def __missing__(self, key):
value = self[key] = type(self)()
return value
# tracking the key sequence when seeking the target
key_list = Tree()
# dict storing the target success result
success = Tree()
# example nested dict of dicts and lists
E = {
'AA':
{
'BB':
{'CC':
{
'DD':
{
'ZZ':'YY',
'WW':'PP'
},
'QQ':
{
'RR':'SS'
},
},
'II':
{
'JJ':'KK'
},
'LL':['MM', 'GG', 'TT']
}
}
}
def find_keys_from_value(data, target):
"""
recursive function -
given a value it returns all the keys in the path to that value within
the dict "data"
there are many paths and many false routes
at the end of a given path if success has not been achieved
the function discards keys to get back to the next possible path junction
"""
print(f"the number of keys in the local dict is {len(data)}")
key_counter = 0
for key in data:
key_counter += 1
# if target has been located stop iterating through keys
if success[target] == 1:
break
else:
# eliminate prior key from path that did not lead to success
if key_counter > 1:
k_list.pop()
# add key to new path
k_list.append(key)
print(f"printing k_list after append{k_list}")
# if target located set success[target] = 1 and exit
if key == target or data[key] == target:
key_list[target] = k_list
success[target] = 1
break
# if the target has not been located check to see if the value
# associated with the new key is a dict and if so return to the
# recursive function with the new dict as "data"
elif isinstance(data[key], dict):
print(f"\nvalue is dict\n {data[key]}")
find_keys_from_value(data[key], target)
# check to see if the value associated with the new key is a list
elif isinstance(data[key], list):
# print("\nv is list\n")
# search through the list
for i in data[key]:
# check to see if the list element is a dict
# and if so return to the recursive function with
# the new dict as "data
if isinstance(i, dict):
find_keys_from_value(i, target)
# check to see if each list element is the target
elif i == target:
print(f"list entry {i} is target")
success[target] = 1
key_list[target] = k_list
elif i != target:
print(f"list entry {i} is not target")
print(f"printing k_list before pop_b {k_list}")
print(f"popping off key_b {key}")
# so if value is not a key and not a list and not the target then
# discard the key from the key list
elif data[key] != target:
print(f"value {data[key]} is not target")
print(f"printing k_list before removing key_before {k_list}")
print(f"removing key_c {key}")
k_list.remove(key)
# select target values
values = ["PP", "SS", "KK", "TT"]
success = {}
for target in values:
print(f"\nlooking for target {target}")
success[target] = 0
k_list = []
find_keys_from_value(E, target)
print(f"\nprinting key_list for target {target}")
print(f"{key_list[target]}\n")
print("\n****************\n\n")