How can I add multiple dict to one multiple? - python

I would like to have a dict like:
dict_a= {
'abc' : {'a':[1,2,3], 'b':[4,5,6], 'c':[7,8,9]},
'efg' : {'a':[10,11,12], 'b':[13,14,15], 'c':[16,17,18]},
'hij' : {'a':[21,22,23], 'b':[24,25,26], 'c':[27,28,29]}
}
so I separate into 2 dict
dict_b = {
'a': [],
'b': [],
'c': []
}
dict_a= {
'abc': {},
'efg': {},
'hij'
}
When I put data by using for loop, the last data will cover earlier data. The following is my code:
for x in sorted(dict_a):
for y in sorted(dict_b):
list= []
...
dict_b[y] = list
dict_a[x] = dict_b
and the result is:
dict_a= {
'abc' : {'a':[21,22,23], 'b':[24,25,26], 'c':[27,28,29]},
'efg' : {'a':[21,22,23], 'b':[24,25,26], 'c':[27,28,29]},
'hij' : {'a':[21,22,23], 'b':[24,25,26], 'c':[27,28,29]}
}
My expected result is:
dict_a= {
'abc' : {'a':[1,2,3], 'b':[4,5,6], 'c':[7,8,9]},
'efg' : {'a':[10,11,12], 'b':[13,14,15], 'c':[16,17,18]},
'hij' : {'a':[21,22,23], 'b':[24,25,26], 'c':[27,28,29]}
}
How can I solve it?
Update full code:
for market in sorted(MARKET_LUT):
for type in sorted(STOCK_TYPE_LUT):
try:
list = []
data = pd.read_csv(file_path, sep=' ', header=None, names=['code', 'name'])
list = data.code.tolist()
dict_b [type] = list
except Exception as e:
traceback.print_exc()
err = sys.exc_info()[1]
LOG_write_log(LOG_ERROR, str(err))
dict_a[x] = dict_b

Replace
for x in sorted(dict_a):
for y in sorted(dict_b):
list= []
...
dict_b[y] = list
dict_a[x] = dict_b
by
for x in sorted(dict_a):
new_dict = dict()
for y in sorted(dict_b):
list= []
...
new_dict[y] = list
dict_a[x] = new_dict

I can't get the exact result you want, but this seems close and illustrates how to avoid the problem you have about the last data covering earlier data.
from pprint import pprint
dict_b = {
'a': [],
'b': [],
'c': []
}
dict_a= {
'abc': {},
'efg': {},
'hij': {}
}
count = 1
for x in sorted(dict_a):
dict_temp = dict_b.copy() # Copy empty dict.
for y in sorted(dict_b):
lst = list(range(count, count+3))
dict_temp[y] = lst
count += 3
dict_a[x] = dict_temp
pprint(dict_a)
Result:
{'abc': {'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]},
'efg': {'a': [10, 11, 12], 'b': [13, 14, 15], 'c': [16, 17, 18]},
'hij': {'a': [19, 20, 21], 'b': [22, 23, 24], 'c': [25, 26, 27]}}

Related

Python create dictionary from dataframe in loop

first post!
I am trying to create a function that create dictionary in loop from a dataframe.
Assume those 2 simplistic dataframes already exist:
data1 = {'A':[1, 2, 3, 4], 'B':[5, 6, 7, 8]}
df1 = pd.DataFrame(data)
dataframe1
and
data2 = {'C':[9, 10], 'D':[11, 12], 'E':[13, 14] }
df2 = pd.DataFrame(data2)
dataframe2
I want to be able to create a function like this:
def create_dict(df):
where the end results of df1 is:
dict1 = { 'A' : 1, 'B' : 5}
dict2 = { 'A' : 2, 'B' : 6}
dict3 = { 'A' : 3, 'B' : 7}
dict4 = { 'A' : 4, 'B' : 8}
and the end results of df2 is:
dict1 = { 'C' : 9, 'D' : 11, 'E' : 13}
dict2 = { 'C' : 10, 'D' : 12, 'E' : 14}
I was looking at dictionary comprehension to handle this, but I'm obviously not sure how to handle that problem. Thanks!
Use pandas.DataFrame.to_dict with records:
df1.to_dict(orient="records")
Output:
[{'A': 1, 'B': 5}, {'A': 2, 'B': 6}, {'A': 3, 'B': 7}, {'A': 4, 'B': 8}]

Group dictionary by multiple keys in python

{
04-21: {
a: [1,2,3,4]
a: [5,6,7]
b: [8,9]
}
04-22: {
a: [1,3,4]
a: [2,6,7]
a: [3,8]
b: [1,4,2]
b: [8,9]
}
}
How do I group this dictionary by first and second value to produce:
{
04-21:{
a: [1,2,3,4,5,6,7]
b: [8,9]
}
04-22:{
a: [1,3,4,2,6,7,3,8]
b: [1,4,2,8,9]
}
Following code gives me error:
for key, group in itertools.groupby(L, lambda x: x[0] ,x[1]):
print(key + " :", list(group))
As soon as you execute that dictionary in Python i.e.:
d = {'04-21': {
'a': [1,2,3,4],
'a': [5,6,7],
'b': [8,9]
},
'04-22': {
'a': [1,3,4],
'a': [2,6,7],
'a': [3,8],
'b': [1,4,2],
'b': [8,9]
}
}
The dictionary becomes:
{'04-21': {'a': [5, 6, 7], 'b': [8, 9]}, '04-22': {'a': [3, 8], 'b': [8, 9]}}

adding value in nested dictionaries in python

I am trying to add value to inside dictionary.
aDict = { "id" :
{"name": None },
"id2" :
{"foo": None},
...
}
for k, v in aDict.items():
temp = [1,2,3,4]
aDict[k][v] = temp
then I got error, TypeError: unhashable type: 'dict'
How can I add value in nested dictionary?
---edit ---
My expected output is,
aDict = { "id" :
{"name": [1,2,3,4] },
"id2" :
{"foo": [1,2,3,4] },
...
}
When you do aDict[k], you already got the value which is dict and then you assign the temp to the specific key of the dict.
aDict = { 'id' :
{'name': None },
'id2':
{'foo':None}
}
for k, v in aDict.items():
temp = [1,2,3,4]
for keys in v.keys():
aDict[k][keys] = temp
Output
{'id': {'name': [1, 2, 3, 4]}, 'id2': {'foo': [1, 2, 3, 4]}}
For any arbitrary dictionary of dictionaries (no matter how deep it is), this works:
def go_deeper(aDict):
for k, v in aDict.items():
if v is None:
aDict[k] = temp
else:
go_deeper(v)
return aDict
Usage:
>>> temp = [1,2,3,4]
>>> go_deeper(aDict)
For example, for input:
aDict = { 'id' :
{'name': None },
"id2" :
{"foo":
{'bar': None }
}
}
the above code returns:
{'id': {'name': [1, 2, 3, 4]}, 'id2': {'foo': {'bar': [1, 2, 3, 4]}}}
Try this :
temp = [1,2,3,4]
for k in aDict:
for j in aDict[k]:
aDict[k][j]=temp
OUTPUT :
{'id': {'name': [1, 2, 3, 4]}, 'id2': {'foo': [1, 2, 3, 4]}}
You can get all keys by using d.keys() then add temp to this dictionary.
aDict = { "id" :
{"name": None },
"id2" :
{"foo": None},
"id3" :
{"bar": None, "boo": None},
}
temp = [1, 2, 3, 4]
for k, v in aDict.items():
for newKey in v.keys():
v[newKey] = temp
Result:
{'id': {'name': [1, 2, 3, 4]},
'id2': {'foo': [1, 2, 3, 4]},
'id3': {'bar': [1, 2, 3, 4], 'boo': [1, 2, 3, 4]}}
I would avoid the use of nested loops. And hence to get your desired output, I would do the following:
aDict = { "id" :
{"name": None },
"id2" :
{"foo": None}
}
for value in aDict.values():
temp = [1,2,3,4]
# obtain the key of inner dictionary
# this line could be written even better, if you're concerned about memory!
key = list(value.keys())[0]
# update the inner value
value[key] = temp
When I run this it gives your desired output
user#Kareems-MBP:Desktop$ python aDict.py
{'id': {'name': [1, 2, 3, 4]}, 'id2': {'foo': [1, 2, 3, 4]}}
Lastly, the TypeError you were getting TypeError: unhashable type: 'dict' is because you're trying to reference an item in the dictionary using a dictionary. Items in a dictionary can be referenced only using their keys. E.g. if we have the following dictionary:
myDict = {
'firstname': 'John',
'lastname': 'White'
}
and we want to reference the first item, we can do that only using myDict['firstname'], we cannot do that even with indices myDict[0]. You can imagine that you were doing something like this myDict[{'firstname': 'John'}].
I hope this has been helpful!

Create a dict from two lists of dicts with matching value

I have two lists of dictionaries, dict1 and dict2.
dict1 = [
{
'id': 0,
'name': 'James'
}, {
'id': 1,
'name': 'Bob'
}
]
dict2 = [
{
'id': 0,
'name': 'James'
}, {
'id': 1,
'name': 'James'
}, {
'id': 2,
'name': 'Bob'
}
]
And i want to create a dict like that:
result = {'James': [0, 1], 'Bob': [2]}
With the names from dict1 as keys and as value the list of "id" fields having the same name.
What's a clean way to do that in Python?
IIUC, I believe last line should be Bob and not James. That way, using pandas
import pandas as pd
>>> df1 = pd.DataFrame(dict1)
>>> df2 = pd.DataFrame(dict2)
>>> df2.groupby('name').agg(list).to_dict()['id']
{'Bob': [2], 'James': [0, 1]}
To filter only names that are in dict1,
>>> df2 = df2[df2['name'].isin(df1['name'])]
and group and agg after that
You can put the names in dict1 in a set first, so that when you iterate over dict2, you can check if the current name is in the set before adding it to the resulting dict of lists:
names = {d['name'] for d in dict1}
result = {}
for d in dict2:
if d['name'] in names:
result.setdefault(d['name'], []).append(d['id'])
result becomes:
{'James': [0, 1], 'Bob': [2]}
You can also do it in pure Python as following:
dict1 = [
{
'id': 0,
'name': 'James'
}, {
'id': 1,
'name': 'Bob'
}
]
dict2 = [
{
'id': 0,
'name': 'James'
}, {
'id': 1,
'name': 'James'
}, {
'id': 2,
'name': 'Bob'
}
]
names = [elem['name'] for elem in dict1]
result = dict((name,[]) for name in names)
for elem in dict2:
result[elem['name']].append(elem['id'])
print(result)
Output:
{'James': [0, 1], 'Bob': [2]}
IIUC, here's a defaultdict solution:
>>> from collections import defaultdict
>>>
>>> result = defaultdict(list)
>>> names = {d['name'] for d in dict1}
>>>
>>> for d in dict2:
...: name = d['name']
...: if name in names:
...: result[name].append(d['id'])
...:
>>> result
defaultdict(list, {'Bob': [2], 'James': [0, 1]})

How can i add the terms of one dict to another?

Let's assume i start with this dictionary:
mydict = {
'a': [[2,4], [5,6]],
'b': [[1,1], [1,7,9], [6,2,3]],
'c': [['a'], [4,5]],
}
How can i append values to 'a' yet be able to add a new key if i needed to let's say 'd' what i tried is
plus_min_dict = {}
plus_min_dict[key] = reference_dataset[key][line_number]
but it only gave one value per key apparently = destroyed the previous value, i want to update or append yet still be able to create a new key if it doesn't exist
Edit: To clarify let's assume this is my initial dictionary:
mydict = {
'a': [[2,4]],}
i do other calculations with another dictionary let's assume it's :
second_dict = {
'a': [ [5,6]],
'b': [[1,1], [1,7,9]],
'c': [['a'], [4,5]],
}
these calculations showed me that i have interest in [5,6] of 'a' and [1,7,9] of 'b' so i want mydict to become:
mydict = {
'a': [[2,4], [5,6]],
'b': [[1,7,9]],
}
If I understand well your question, you want to append a new value to your dictionary if the key already exists. If so, I would use a defaultdict for a simple reason. With a defaultdict you can use the method += to create (if does not exist) or add (if exist) an element :
from collections import defaultdict
# Your dictionaries
mydict = {
'a': [[2,4], [5,6]],
'b': [[1,1], [1,7,9], [6,2,3]],
'c': [['a'], [4,5]],
}
plus_min_dict = {'a': [[3,3]]}
# d is a DefaultDict containing mydict values
d=defaultdict(list,mydict)
# d_new is a DefaultDict containing plus_min_dict dict
d_new = defaultdict(list, plus_min_dict)
# Add all key,values of d in d_new
for k, v in d.items():
d_new[k] += d[k]
print(d_new)
Results :
defaultdict(<class 'list'>, {'c': [['a'], [4, 5]], 'a': [[3, 3], [2, 4], [5, 6]], 'b': [[1, 1], [1, 7, 9], [6, 2, 3]]})
Use an if else loop
mydict = {'a': [[2,4]],}
second_dict = {
'a': [ [5,6]],
'b': [[1,1], [1,7,9]],
'c': [['a'], [4,5]]}
missing_values = {
'a': [5,6],
'b': [1,7,9]}
for key, value in missing_values.items():
if key in mydict:
mydict[key ].append(value)
else:
mydict[key ] = [value]
print(mydict)
Result:
{'a': [[2, 4], [5, 6]], 'b': [[1, 7, 9]]}
To append an item into 'a', you can do this:
mydict['a'] += ['test_item']
Or:
mydict['a'].append('test_item')
You can just append:
mydict = {
'a': [[2,4], [5,6]],
'b': [[1,1], [1,7,9], [6,2,3]],
'c': [['a'], [4,5]],
}
mydict['a'].append([7,8])
mydict['d'] = [0,1]
print(mydict)

Categories