Combine elements from list of lists based on name - python-3.x

I am new to Python, so I may have the name of this wrong. The issue I am having is, I have a list as follow
lst1 = [{'A': ['99']}, {'B': ['83']}, {'D': ['65']}, {'J': ['90']}, {'A': ['99']}, {'B': ['85']}, {'D': ['63']}, {'J': ['89']}, {'A': ['95']}, {'B': ['79']}, {'D': ['63']}, {'J': ['73']}, {'A': ['98']}, {'B': ['82']}, {'D': ['81']}, {'J': ['91']}]
I am trying to see if there is a way to combine the the element within the [] that have the same key, so the resulting list will be
new_lst = [{'A': [99, 99, 95, 98]}, {'B': [83, 85, 79, 82]}, {'D': [65, 63, 63, 81]}, {'J': [90, 89, 73, 91]}]
I have been banging my head against the monitor for a few days now and I cannot figure it out, I would definitely appreciate any help.
Thank you,

If the output format has to be a list of dictionaries like the input, this is very complicated. It gets easy if you use a dictionary directly for the output. You then can use dict.setdefault(...):
inputlist = [
{'A': ['99']},
{'B': ['83']},
{'D': ['65']},
{'J': ['90']},
{'A': ['99']},
{'B': ['85']},
{'D': ['63']},
{'J': ['89']},
{'A': ['95']},
{'B': ['79']},
{'D': ['63']},
{'J': ['73']},
{'A': ['98']},
{'B': ['82']},
{'D': ['81']},
{'J': ['91']}
]
output = dict()
for dct in inputlist:
key = list(dct.keys())[0] # get the letter (A, B, D, J)
output.setdefault(key, []) # create the key in the output dictionary and assign a list to it, if it doesn't exist already
output[key] += dct[key] # append the number
print(output)
Output:
{'A': ['99', '99', '95', '98'], 'B': ['83', '85', '79', '82'], 'D': ['65', '63', '63', '81'], 'J': ['90', '89', '73', '91']}

Related

How can we include only specific json fields for comparision in deepdiff pyhton?

Here, we have 2 JSON, I want to include only 'id' field for comparison, rest of the fields should be ignored.
j1 = {'MyList': [{'a': 1, 'b': 2, 'c': [{'id': '1'}]},
{'a': 1, 'b': 2, 'c': [{'id': '2'}]}], "j": "2222"}
j2 = {'MyList': [{'a': 1, 'b': 2, 'c': [{'id': '4'}]},
{'a': 1, 'b': 2, 'c': [{'id': '7'}]}], "j": "7777"}
Please suggest, How we can achieve this using DeepDiff.

Strange behavior by list of dictionaries [duplicate]

This question already has answers here:
How to copy a dictionary and only edit the copy
(23 answers)
Closed 1 year ago.
I have a list of dictionaries as follows:
a = [{'a':1, 'b':2, 'c':3}, {'d':4, 'e':5, 'f':6}]
Now I want another list b to have same contents as a but with one (key,value) pair extra. So I do it as:
b = a.copy()
for item in b:
item['x'] = 6
But now both the lists a and b have 'x': 6 sitting in them.
>>> b
[{'a': 1, 'b': 2, 'c': 3, 'x': 6}, {'d': 4, 'e': 5, 'f': 6, 'x': 6}]
>>> a
[{'a': 1, 'b': 2, 'c': 3, 'x': 6}, {'d': 4, 'e': 5, 'f': 6, 'x': 6}]
I also tried this:
c = a[:]
for item in c:
item['q'] = 12
And now all the three lists have 'q': 12.
>>> c
[{'a': 1, 'b': 2, 'c': 3, 'x': 6, 'q': 12}, {'d': 4, 'e': 5, 'f': 6, 'x': 6, 'q': 12}]
>>> b
[{'a': 1, 'b': 2, 'c': 3, 'x': 6, 'q': 12}, {'d': 4, 'e': 5, 'f': 6, 'x': 6, 'q': 12}]
>>> a
[{'a': 1, 'b': 2, 'c': 3, 'x': 6, 'q': 12}, {'d': 4, 'e': 5, 'f': 6, 'x': 6, 'q': 12}]
I can't understand how is this working. This would have been acceptable if I had done b = a. But why for b = a.copy() and c = a[:].
Thanks in advance:)
To copy a dictionary and copy all referenced objects use the deepcopy() function from the copy module instead of dict's method copy().
import copy
a = [{'a':1, 'b':2, 'c':3}, {'d':4, 'e':5, 'f':6}]
b = copy.deepcopy(d)
You can use #maziyank's solution. The explanation is that except copy.deepcopy() all the methods are just pointing one variable to the previous variable.
Thus any change to any of them will transcend to all the variables that point to the same variable.

Problem using itertools and zip in combination to create dictionary from two lists of different lengths

I want keys to repeat the same way in each dictionary. I.e. start from A and go till E. But it seems itertools.cycle is skipping one every time it cycles over. I also want the values to follow the order in the list (i.e. start from 1 in the first dictionary and end with 15 in the last dictionary). Please see code below:
import itertools
allKeys=['A','B','C','D','E']
a=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
g=itertools.cycle(allKeys)
b=[]
for i in range(3):
dishDict=dict(zip(g,a))
b.append(dishDict)
b
Generates:
[{'A': 11, 'B': 12, 'C': 13, 'D': 14, 'E': 15},
{'B': 11, 'C': 12, 'D': 13, 'E': 14, 'A': 15},
{'C': 11, 'D': 12, 'E': 13, 'A': 14, 'B': 15}]
As you see, keys in the second dictionary start from B (instead of A, as I would like). Also the values are the same in all three dictionaries in the list.
This is what I want the output to look like:
[{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5},
{'A': 6, 'B': 7, 'C': 8, 'D': 9, 'E': 10},
{'A': 11, 'B': 12, 'C': 13, 'D': 14, 'E': 15}]
I'd really appreciate it if someone could shed some light on what's happening and what I should do to fix it. I have already spent quite a bit of time to solve it myself and also checked the documentation on itertools.cycle. But haven't been able to figure it out yet.
For the required output, you don't need cycle():
allKeys=['A','B','C','D','E']
a=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
it = iter(a)
b=[]
for i in range(3):
dishDict=dict(zip(allKeys,it))
b.append(dishDict)
print(b)
Prints:
[{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5},
{'A': 6, 'B': 7, 'C': 8, 'D': 9, 'E': 10},
{'A': 11, 'B': 12, 'C': 13, 'D': 14, 'E': 15}]

How to extend values in dictionaries using key in Python

How do I extend the values in a dictionary from a list of dictionaries using the keys as the main constraint, say:
d = {'a': (), 'b': 0, 'c': "", d: ""}
l = [ {'a': (23, 48), 'b': 34, 'c': "fame", d: "who"},
{'a': (94, 29), 'b': 3, 'c': "house", d: "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", d: "stack"},
]
to give
d = {'a': [(23, 48), (94,29), 23,12], 'b': [34, 3, 94],
'c': ["fame", "house", "imap"], 'd': ['who', 'cats', 'stack'] }
code used
for i in l:
d["a"].extend(i.get('a')),
d["b"].extend(i.get('b')),
d["c"].extend(i.get('c')),
d['d'].extend(i.get('d'))
You should initialize d as an empty dict instead, so that you can iterate through l and the key-value pairs to keep appending the values to the sub-list of d at the given keys:
l = [
{'a': (23, 48), 'b': 34, 'c': "fame", 'd': "who"},
{'a': (94, 29), 'b': 3, 'c': "house", 'd': "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", 'd': "stack"},
]
d = {}
for s in l:
for k, v in s.items():
d.setdefault(k, []).append(v)
d becomes:
{'a': [(23, 48), (94, 29), (23, 12)],
'b': [34, 3, 93],
'c': ['fame', 'house', 'imap'],
'd': ['who', 'cats', 'stack']}
If the sub-dicts in l may contain other keys, you can instead initialize d as a dict of empty lists under the desired keys:
l = [
{'a': (23, 48), 'b': 34, 'c': "fame", 'd': "who"},
{'a': (94, 29), 'b': 3, 'c': "house", 'd': "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", 'd': "stack"},
{'e': 'choices'}
]
d = {k: [] for k in ('a', 'b', 'c', 'd')}
for s in l:
for k in d:
d[k].append(s.get(k))
in which case d becomes:
{'a': [(23, 48), (94, 29), (23, 12), None],
'b': [34, 3, 93, None],
'c': ['fame', 'house', 'imap', None],
'd': ['who', 'cats', 'stack', None]}
You can use defaultdict as follow since the default value is an empty list (https://docs.python.org/2/library/collections.html#collections.defaultdict)
import collections
d = collections.defaultdict(list)
keys = ['a', 'b', 'c', 'd']
for i in l:
for k in keys:
d[k].append(i[k])
print(d)
Best regard

Converting specific values from a dictionary to float

I have this dictionary
dict_X = {
'A': {'a': 371, 'b': 4925, 'c': 39, 'd': 8},
'B': {'a': 400, 'b': 4659, 'c': 37, 'd': 11},
'C': {'a': 19, 'b': 214, 'c': 1, 'd': 1},
'D': {'a': 16, 'b': 115, 'c': 0, 'd': 1}
}
I need to convert the values of 'c' and 'd' to float and find ratio of 'c' to 'd'.
I know that I have to use float() method, what I cannot figure out is how to use that for the values in a dictionary within a dictionary.
Need to convert the values to 'c' and 'd' to float to find the ratio of 'c':'d'. Thank you guys for the help.
The code you posted in the comments is almost correct, except you forgot to retain the keys for the inner dict, making the nested structures sets instead. The correct dict comprehension would be:
{outer_k: {inner_k: float(inner_v) for inner_k, inner_v in outer_v.items()} for outer_k, outer_v in dict_X.items()}
However, this converts all the values (a,b,c,d) into floats instead of just c and d. You can limit it to only those keys using the following if-else condition:
{outer_k: {inner_k: float(inner_v) if inner_k in ['c','d'] else inner_v for inner_k, inner_v in outer_v.items()} for outer_k, outer_v in dict_X.items()}
Or, since according to what you said you only need the float conversion for a calculation, just cast it before using it in that expression and leave dict_X as it is. For example,
float_ratio = float(dict_X['A']['c'])/dict_X['A']['d']
Converting just one of them is enough to make the result a float.

Resources