How do I merge dictionaries having similar values in Python? - python

I have a problem.
Input=[
{'id':uuid1(),'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'id':uuid1(),'name':'cpu','point':[{'second':10,'severity':'warning'}],'date':'2021-09-13','PO':3},
{'id':uuid1(),'name':'cpu','point':[{'second':20,'severity':'critical'}],'date':'2021-09-14','PO':3},
{'id':uuid1(),'name':'cpu','point':[{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}]
I will compare in this array. If the same name, I will combine all value of this dict.
It mean combine all value of key 'point'. I will have key list 'point' with multi dict
We have many duplicate key name = 'cpu'. So I will combine all value if the same value.U see we have PO the same value (PO=3 with name=cpu).If different value, we will take the last value(last value 'date':'2021-09-15').Finally, we will append the dicts in the key point list together
Desired result
Output=[
{'id':uuid1(),'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'id':uuid1(),'name':'cpu','point':[{'second':10,'severity':'warning'},
{'second':20,'severity':'critical'},
{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}
]
Note: I use python 3.6
I hope someone will help me. Thank you very muck

There is probably a better way to do this but the following works:
a=[{'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'name':'cpu','point':[{'second':10,'severity':'warning'}],'date':'2021-09-13','PO':3},
{'name':'cpu','point':[{'second':20,'severity':'critical'}],'date':'2021-09-14','PO':3},
{'name':'cpu','point':[{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}]
b=[]
for i in a:
for j in b:
if i['name'] == j['name']:
j['point'] += i['point']
break
else:
b.append(i)

Related

Trying to call the first element of a tuple by the value of the second element (within a loop)

The title is a bit confusing but I am essentially trying to store the name x of a tuple (x,y) by calling the values of y. The tuples are in a list, and there are three of them. However, this data may change so I want this loop to be able to process any sort of list length as long as the form comes in tuples. Additionally my tuples are in (str, [list]) form. Here is an example of my code.
key, val = list(d.keys()), list(d.values())
for i in val:
if i == group_ids[0]:
for x,y in list(d.items()):
if y == i:
print(x,y)
I have created a defaultdict previously in order to access my list of tuples in (str, [list]) format because ipywidgets8 no longer accepts dictionaries. After having successfully selected the list of values based on the str in the widgets interface I am looking to store the name of the selected list so that I can save each file based on their respective name. I know with pandas dataframe you can call the value of one column based on the value of another with .loc and I am trying to do something similar with my list of tuples but cannot figure out how. The group_ids variable is the list of selected values received from the ipywidgets button. I have to call [0] position because it has been stored with double brackets. Even more simply put, I want (this is not in any coding language just how my brain can best present this in human words):
FOR i IN val,
if i == group_ids[0]
PRINT x of key at the index where i in val is found
I hope this explanation is clear. I feel that this should not be so difficult to figure out but for some reason I cannot.
EDIT:
A sample of my data
group_ids = [[5876233, 5883627, 5891029, 5892881, 5896571, 5900242, 5902043, 5905766, 5905796, 5913064, 5913075, 5913080, 5914875, 5920356, 5924048, 5925824, 5927655, 5929456, 5929479, 5931307, 5934950, 5936704, 5940344, 5943972, 5944002, 5945785, 5947627, 5951172, 5951181, 5954751, 5958339, 5958354, 5958358, 5965416, 5965424, 5967145, 5968843, 5972099, 5978640, 5981887, 5983501, 5993193, 5967178, 5967171, 5963649, 5951209, 5929476, 5958331, 5938533, 5933134, 5918577, 5958359]]
list(d.items()) = [('Libraries', [5876233, 5883627, 5891029, 5892881, 5896571, 5900242, 5902043, 5905766, 5905796, 5913064, 5913075, 5913080, 5914875, 5920356, 5924048, 5925824, 5927655, 5929456, 5929479, 5931307, 5934950, 5936704, 5940344, 5943972, 5944002, 5945785, 5947627, 5951172, 5951181, 5954751, 5958339, 5958354, 5958358, 5965416, 5965424, 5967145, 5968843, 5972099, 5978640, 5981887, 5983501, 5993193, 5967178, 5967171, 5963649, 5951209, 5929476, 5958331, 5938533, 5933134, 5918577, 5958359]), ('Sport Facilities', [5812360, 5817970, 5818061, 5821851, 5823750, 5823751, 5827499, 5829344, 5829423, 5831312, 5833208, 5838752, 5840647, 5842526, 5842539, 5842575, 5842583, 5844396....)]
d.keys = dict_keys(['Libraries', 'Sports Facilities', 'Youth Facilities'])
I want the respective key for the list of ids seen in the group_ids variable
So I think you just need:
for k, v in d.items():
if v[0] == group_ids[0]:
print(k, v)
Checking if v == group_ids would be more precise, but I assume that all ids are different.

Python Comparing Values of Numpy Array Between 2 Dictionaries Value

I have 2 dictionary and an input
letter = 'd'
dict_1 = {"label_1": array(['a','b']), "label_2": array(['c','d']), ...}
dict_2 = {"label_1": array(['x','y']), "label_2": array(['z','o']), ...}
letter_translated = some_function(letter)
output desired: 'o'
What I have in mind right now is to get the index number from the array of the key "label_2" in dict_1 then searching for the same index in dict_2. I am open to other way of doing it. If you are unclear about the question, feel free to drop a comment.
Note: the arrays are numpy arrays
I propose to iterate through the first dictionary, while keeping a trace of how to get to the current element (key and i) so that we can look in the second dict in the same place:
from numpy import array
dict_1 = {"label_1": array(['a','b']), "label_2": array(['c','d'])}
dict_2 = {"label_1": array(['x','y']), "label_2": array(['z','o'])}
def look_for_corresponding(letter, d1, d2):
for key, array_of_letters in d1.items():
for position, d1_letter in enumerate(array_of_letters):
if d1_letter == letter:
return d2[key][position]
return None # Line not necessary, but added for clarity
output = look_for_corresponding('d', dict_1, dict_2)
print(output)
# o
Of course, this code will fail if dict_1 and dict_2 do not have exactly the same structure, or if the arrays are more than 1D. If those cases apply to you, please edit your question to indicate it.
Also, I am not sure what should be done if the letter is not to be found within dict_1. This code will return None, but it could also raise an exception.
What do you mean with 'index'? The number?
dictionaries don't have the concept of counted indices of their entries. You can only access data through the key (here "label_2"), or by iterating (for key in dict_1 ...).
The order is not guaranteed and can change. The order or your declaration is not kept.
If you wish to have "label_2" in both, then you need to access
key = "label_2"
item_from_1 = dict_1[key]
item_from_2 = dict_2[key]
If you need to iterate dict_1, then on each item find the appropriate item in the second, then this also needs to go over the key:
for (key,value1) in dict_1.iteritems():
value2 = dict_2[key]
.....
Note that the order the items come up in the loop may vary. Even from one run of the program to the next.

Indexing Dict with Multiple values at one key

I'm new to python and I was wondering if there's a way for me to pull a value at a specific index. Let's say I have a key with multiple values(list) associated with it.
d = {'ANIMAL' : ['CAT','DOG','FISH','HEDGEHOG']}
Let's say I want to iterate through values and print out the value if it's equal to 'DOG'. Do Values, Key pairs have a specific index associated with the position of Values?
I've try reading up on dict and how it works apparently you can't really index it. I just wanted to know if there's a way to get around that.
You can perform the following (comments included):
d = {'ANIMAL' : ['CAT','DOG','FISH','HEDGEHOG']}
for keys, values in d.items(): #Will allow you to reference the key and value pair
for item in values: #Will iterate through the list containing the animals
if item == "DOG":
print(item)
print(values.index(item)) #will tell you the index of "DOG" in the list.
So maybe this will help:
d = {'ANIMAL' : ['CAT','DOG','FISH','HEDGEHOG']}
for item in d:
for animal in (d[item]):
if animal == "DOG":
print(animal)
Update -What if I want to compare the string to see if they're equal or not... let say if the value at the first index is equal to the value at the second index.
You can use this:
d = {'ANIMAL' : ['CAT','DOG','FISH','HEDGEHOG']}
for item in d:
for animal in (d[item]):
if animal == "DOG":
if list(d.keys())[0] == list(d.keys())[1]:
print("Equal")
else: print("Unequal")
Keys and values in a dictionary are indexed by key and do not have a fixed index like in lists.
However, you can leverage the use of 'OrderedDict' to give an indexing scheme to your dictionaries. It is seldom used, but handy.
That being said, dictionaries in python3.6 are insertion ordered :
More on that here :
Are dictionaries ordered in Python 3.6+?
d = {'animal': ['cat', 'dog', 'kangaroo', 'monkey'], 'flower': ['hibiscus', 'sunflower', 'rose']}
for key, value in d.items():
for element in value:
if element is 'dog':
print(value)
does this help? or, you want to print index of key in dictionary?

Python dictionary check if the values match with other key values

I have created a python dictionary with a structure like :-
mydict = {'2018-08' : [32124,4234,23,2323,32423,342342],
'2018-07' : [13123,23424,2,3,4343,4232,2342],
'2018-06' : [1231,12,12313,12331,3123131313,434546,232]}
I want to check if any value in the values of key '2018-08' match with any values of other keys. is there a short way to write this?
You can simply loop over your expected values of mydict, and then for each of them check if its present in any of the values of the dictionary
You can use the idiom if item in list to check if item item is present in the list list
expected_values = mydict['2018-08']
found = False
for expected in expected_values:
for key in mydict:
if expected in mydict[key]:
found = True
break
Take into account that is a brute force algorithm and it may not be the optimal solution for larger dictionaries
The question is vague, so I am assuming that you want the values in the target month (e.g. 2018-08) that are contained somewhere within the other months.
Sets are much faster for testing membership compared to list iteration.
target = '2018-08'
s = set()
for k, v in mydict.iteritems():
if k != target:
s.update(v)
matches = set(mydict[target]) & s
Can use itertools.chain to create a long list
import itertools
for key,value in mydict.items():
temp_dict = mydict.copy()
temp_dict.pop(key)
big_value_list=list(itertools.chain(*temp_dict.values()))
print(key, set(value) & set(big_value_list))
Dry run by changing your provided inputs
mydict = {'2018-08' : [32124,4234,23,2323,32423,342342],
'2018-07' : [13123,23424,2,3,4343,4232,2342],
'2018-06' : [1231,12,12313,12331,3123131313,434546,232,342342,2342]}
Output:
('2018-08', set([342342]))
('2018-07', set([2342]))
('2018-06', set([342342, 2342]))

Python: How to traverse a List[Dict{List[Dict{}]}]

I was just wondering if there is a simple way to do this. I have a particular structure that is parsed from a file and the output is a list of a dict of a list of a dict. Currently, I just have a bit of code that looks something like this:
for i in xrange(len(data)):
for j, k in data[i].iteritems():
for l in xrange(len(data[i]['data'])):
for m, n in data[i]['data'][l].iteritems():
dostuff()
I just wanted to know if there was a function that would traverse a structure and internally figure out whether each entry was a list or a dict and if it is a dict, traverse into that dict and so on. I've only been using Python for about a month or so, so I am by no means an expert or even an intermediate user of the language. Thanks in advance for the answers.
EDIT: Even if it's possible to simplify my code at all, it would help.
You never need to iterate through xrange(len(data)). You iterate either through data (for a list) or data.items() (or values()) (for a dict).
Your code should look like this:
for elem in data:
for val in elem.itervalues():
for item in val['data']:
which is quite a bit shorter.
Will, if you're looking to decend an arbitrary structure of array/hash thingies then you can create a function to do that based on the type() function.
def traverse_it(it):
if (isinstance(it, list)):
for item in it:
traverse_it(item)
elif (isinstance(it, dict)):
for key in it.keys():
traverse_it(it[key])
else:
do_something_with_real_value(it)
Note that the average object oriented guru will tell you not to do this, and instead create a class tree where one is based on an array, another on a dict and then have a single function to process each with the same function name (ie, a virtual function) and to call that within each class function. IE, if/else trees based on types are "bad". Functions that can be called on an object to deal with its contents in its own way "good".
I think this is what you're trying to do. There is no need to use xrange() to pull out the index from the list since for iterates over each value of the list. In my example below d1 is therefore a reference to the current data[i].
for d1 in data: # iterate over outer list, d1 is a dictionary
for x in d1: # iterate over keys in d1 (the x var is unused)
for d2 in d1['data']: # iterate over the list
# iterate over (key,value) pairs in inner most dict
for k,v in d2.iteritems():
dostuff()
You're also using the name l twice (intentionally or not), but beware of how the scoping works.
well, question is quite old. however, out of my curiosity, I would like to respond to your question for much better answer which I just tried.
Suppose, dictionary looks like: dict1 = { 'a':5,'b': [1,2,{'a':100,'b':100}], 'dict 2' : {'a':3,'b':5}}
Solution:
dict1 = { 'a':5,'b': [1,2,{'a':100,'b':100}], 'dict 2' : {'a':3,'b':5}}
def recurse(dict):
if type(dict) == type({}):
for key in dict:
recurse(dict[key])
elif type(dict) == type([]):
for element in dict:
if type(element) == type({}):
recurse(element)
else:
print element
else:
print dict
recurse(dict1)

Categories