How to turn this list -
list = ['your name', 'mother', 'age', '43']
into this dictionary of dictionaries -
dict = {'your name':
{'mother':
{'age': '43'}
}
}
One option is to iterate backwards over the list, and continuously update the result dict D:
L = ['your name', 'mother', 'age', '43']
D = L[-1] # '43'
for k in L[-2::-1]:
D = {k: D} # {'age': D}... {'mother': D}...
print(D)
Out:
{'your name': {'mother': {'age': '43'}}}
You can just hardcode the logic and then run this in a loop.
l = ['your name', 'mother', 'age', '43']
d = {}
d[l[0]] = {
l[1]: {
l[2]: l[3]
}
}
Related
I have a dict as follows.
dict = {'P': ['Demo'], 'Q': ['PMS']}
And I have a list of Dict as follows.
all = [{'Name': 'PMS'}, {'Name': 'Demo'}]
I need to have the dict's respective value in all as bellow.
new_list = [{'Name': 'PMS','Code': 'Q'}, {'Name': 'Demo','Code': 'P'}]
In this specific case, given that the values are just strings and therefore hashable objects, you can use a dictionary of reverse mappings. Be aware that it could not be used if the values were not hashable.
dct = {'P': ['Demo'], 'Q': ['PMS']}
all = [{'Name': 'PMS'}, {'Name': 'Demo'}]
reverse_mapping = {v[0]:k for k, v in dct.items()}
new_list = [d.copy() for d in all]
for d in new_list:
d['Code'] = reverse_mapping[d['Name']]
print(new_list)
This gives:
[{'Name': 'PMS', 'Code': 'Q'}, {'Name': 'Demo', 'Code': 'P'}]
dct = {'P': ['Demo'], 'Q': ['PMS']}
all_ = [{'Name': 'PMS'}, {'Name': 'Demo'}]
out = [dict(**l, Code=next(k for k, v in dct.items() if l['Name'] in v)) for l in all_]
print(out)
Prints:
[{'Name': 'PMS', 'Code': 'Q'}, {'Name': 'Demo', 'Code': 'P'}]
Or: you can make temporary dictionary:
tmp = {v[0]:k for k, v in dct.items()}
out = [dict(**l, Code=tmp[l['Name']]) for l in all_]
print(out)
You could make an inverted dictionary of codes, then go through the list of dictionaries and add the codes in:
codes = {"P": ["Demo"], "Q": ["PMS"]}
lst = [{"Name": "PMS"}, {"Name": "Demo"}]
inverted_codes = {value: key for key, values in codes.items() for value in values}
# {'Demo': 'P', 'PMS': 'Q'}
for dic in lst:
code = dic["Name"]
dic["Code"] = inverted_codes[code]
print(lst)
Output
[{'Name': 'PMS', 'Code': 'Q'}, {'Name': 'Demo', 'Code': 'P'}]
Input:
my_list = [
{'Name':'Jack', 'Surname': 'Reacher', 'Blogs':{'BlogName': 'python2', 'Date':'20200101' }},
{'Name':'Jack2', 'Surname': 'Reacher2', 'Blogs':{'BlogName':'Python3','Date':'20200201'}}
]
Expected Output:
arr_1 = [ {'Name':'Jack', 'Surname':'Reacher'}, {'Name':'Jack2', 'Surname':'Reacher2'} ]
arr_2 = [ {'ParentId':'Jack', 'BlogName':'python2','Date1':'20200101'},
{'ParentId':'Jack2','BlogName':'Python3','Date1':'20200201'} ]
Output I get:
arr_1 = [ {'Name': 'Jack'}, {'Surname': 'Reacher'}, {'Name': 'Jack2'}, {'Surname': 'Reacher2'} ]
arr_2 = [{'ParentId': 'Jack'}, {'BlogName': 'python2', 'Date': '20200101'},
{'ParentId': 'Jack2'}, {'BlogName': 'Python3', 'Date': '20200201'}]
How should I flatten the dictionary for the 'arr_2' ?
for lis in my_list:
for k, v in lis.items():
if not k == 'Blogs':
arr_1.append({k:v})
for lis in my_list:
for k, v in lis.items():
if k == 'Surname':
continue
elif k == 'Name':
arr_2.append({'ParentId':v})
else:
arr_2.append(v)
print(arr_1)
print(arr_2)
Also, is there a pythonic way to do this ? I feel, I'm over doing it.
Notice how arr2 is processed before arr1. We remove the 'Blogs' inner dict when processing arr2 using pop. Also the ** operator is useful as it flattens a dict.
arr2 = [{'ParentId':d.get('Name'),**d.pop('Blogs')} for d in my_list]
arr1 = my_list[:]
#Output
[{'Name': 'Jack', 'Surname': 'Reacher'}, {'Name': 'Jack2', 'Surname': 'Reacher2'}]
[{'ParentId': 'Jack', 'BlogName': 'python2', 'Date': '20200101'}, {'ParentId': 'Jack2', 'BlogName': 'Python3', 'Date': '20200201'}]
I have a list of dictionaries that looks like the following:
data = [{'Name': 'Paul', 'Date': '20200412', 'ID': '1020'}, {'Name': 'Frank', 'Date': '20200413', 'ID': '1030'}, {'Name': 'Anna', 'Date': '20200414', 'ID': '1040'}]
I need to create a new list of dictionaries, where ID's value would be the key, and the value is another dictionary with key/values associated with this specific ID.
This is the desired output:
new_data = [{'1020': {'Name': 'Paul', 'Date': '20200412'}},
{'1030': {'Name': 'Frank', 'Date': '20200413'}},
{'1040': {'Name': 'Anna', 'Date': '20200414'}}]
I have tried:
for index, my_dict in enumerate(data):
new_data = []
key = my_dict['ID']
new_data.append(key)
But that only assigned the key value, not sure how to push it into into a new dict along with other key/values.
>>> [{i['ID']: {k:v for k,v in i.items() if k != 'ID'}} for i in data]
[{'1020': {'Name': 'Paul', 'Date': '20200412'}},
{'1030': {'Name': 'Frank', 'Date': '20200413'}},
{'1040': {'Name': 'Anna', 'Date': '20200414'}}]
new_data = []
for index, my_dict in enumerate(data):
key = my_dict['ID']
del my_dict['ID']
new_data.append({key:data[index]})
To add the other values you simply need to create a new dict like this:
new_data.append( key:{
'name':my_dict['name']
'Date':my_dict['date']
}
You also don't need to make the 'key' variable, you can just use 'my_dict['ID']'
You could try this list comprehension:
[{x["ID"]: {k: v for k, v in x.items() if k != "ID"}} for x in data]
Which assigns ID as the parent key to the dictionary, and filters out the ID key from the child dictionary inside a dict comprehension
Which could be broken down into this:
result = []
for x in data:
result.append({x["ID"]: {k: v for k, v in x.items() if k != "ID"}})
And even to a straightforward loop approach:
result = []
for x in data:
dic = {x["ID"]: {}}
for k, v in x.items():
if k != "ID":
dic[x["ID"]][k] = v
result.append(dic)
Output:
[{'1020': {'Name': 'Paul', 'Date': '20200412'}}, {'1030': {'Name': 'Frank', 'Date': '20200413'}}, {'1040': {'Name': 'Anna', 'Date': '20200414'}}]
I would like to know how I can change a value in a dictionary using list of keys and 1 value
my_dict = {
'bob': {
'name': {'first': 'FirstName', 'last': 'LastName'},
'job': 'Developer'
}
}
string1 = 'bob.name.first=Bob'
string1 = string.split('=')
string2 = string1[0].split('.')
string2.append(string[1])
Here I end up with a list of 4 items, the first 3 are keys and the last is the value.
How can I use this given list to change the value in my_dict considering that the given list keys number can be changed for example if I want to change bob.job=QA
You can write:
string1 = 'bob.name.first=Bob'
string1,string2 = string1.split('=')
string1 = string1.split('.')
my_dict[string1[0]][string1[1]][string1[2]] = string2
I suppose the following function is what you are looking for, it works with any number of keys and creates intermediates dictionaries if not exist yet.
d = {
'bob': {
'name': {
'first': 'FirstName',
'last': 'LastName'
},
'job': 'Developer'
}
}
def update_dict_by_expr(d, expr):
keys_value = expr.split('=')
keys = keys_value[0].split('.')
value = keys_value[1]
item = d
while len(keys) > 1:
key = keys.pop(0)
if key not in item:
item[key] = {}
item = item[key]
key = keys[0]
item[key] = value
print(d)
update_dict_by_expr(d, 'bob.name.first=Bob Junior')
update_dict_by_expr(d, 'bob.name.birth.date=01/01/2017')
update_dict_by_expr(d, 'bob.name.birth.place=NYC')
print(d)
You want a dict with keys that can be accessed as attributes. You can achieve that by subclassing dict class, and add support for your need. I think this is more pythonic solution as it is much more intuative:
class MyDict(dict):
def __getattr__(self, attr):
return self[attr] if attr in self.keys() else None
def __setattr__(self, attr, value):
self[attr] = value
my_dict = MyDict({
'bob': MyDict(
{'name':
MyDict({'first': 'FirstName', 'last': 'LastName'}),
'job':'Developer'})})
>>> my_dict.bob
{'job': 'Developer', 'name': {'last': 'LastName', 'first': 'FirstName'}}
>>> my_dict.bob.job
'Developer'
>>> my_dict.bob.name
{'last': 'LastName', 'first': 'FirstName'}
It does require some overhead, as you will need to build your dicts based on MyDict. Regular dicts won't work if added to this dict.
This supports setting a new value as well:
>>> my_dict.bob.job = 'QA'
>>> my_dict.bob.job
'QA'
If you want to update Bob's job you can access it using my_dict['bob']['job']
my_dict = {
'bob': {
'name': {'first': 'FirstName', 'last': 'LastName'},
'job': 'Developer'
}
}
my_dict['bob']['job'] = 'QA'
print(my_dict)
>> {'bob': {'name': {'last': 'LastName', 'first': 'FirstName'}, 'job': 'QA'}}
or by splitting your string:
my_dict = {
'bob': {
'name': {'first': 'FirstName', 'last': 'LastName'},
'job': 'Developer'
}
}
bobjob_key_value = 'bob.job=QA'
key, value = bobjob_key_value.split('=')
key = key.split('.')
my_dict[key[0]][key[1]] = value
print(my_dict)
>> {'bob': {'job': 'QA', 'name': {'last': 'LastName', 'first': 'FirstName'}}}
import yaml
def get_dictionary_replace_value(file, new_value, strip_qoutes=True):
with open(file, 'r') as rf:
yaml_doc = yaml.load(rf)
rf.close()
key, value = new_value.split('=')
keys = key.split('.')
inner_dict = yaml_doc
for i in keys[:-1]:
inner_dict = inner_dict[i]
inner_dict[keys[-1]] = value
with open(file, 'w') as wf:
if strip_qoutes:
wf.write(yaml.dump(yaml_doc,
default_flow_style=False).replace("'", "").replace('"', ""))
else:
wf.write(yaml.dump(yaml_doc, default_flow_style=False))
wf.close()
I wanna make a dictionary has name's key & data.In views.py I wrote
data_dict ={}
def try_to_int(arg):
try:
return int(arg)
except:
return arg
def main():
book4 = xlrd.open_workbook('./data/excel1.xlsx')
sheet4 = book4.sheet_by_index(0)
data_dict_origin = OrderedDict()
tag_list = sheet4.row_values(0)[1:]
for row_index in range(1, sheet4.nrows):
row = sheet4.row_values(row_index)[1:]
row = list(map(try_to_int, row))
data_dict_origin[row_index] = dict(zip(tag_list, row))
if data_dict_origin['name'] in data_dict:
data_dict[data_dict_origin['name']].update(data_dict_origin)
else:
data_dict[data_dict_origin['name']] = data_dict_origin
main()
When I printed out data_dict,it is
OrderedDict([(1, {'user_id': '100', 'group': 'A', 'name': 'Tom', 'dormitory': 'C'}), (2, {'user_id': '50', 'group': 'B', 'name': 'Blear', 'dormitory': 'E'})])
My ideal dictionary is
dicts = {
Tom: {
'user_id': '100',
'group': 'A',
'name': 'Tom',
'dormitory': 'C'
},
Blear: {
},
}
How should I fix this?What should I write it?
The code is using the wrong key in the dictionary. The keys are 1, 2, and do not have the name key. You can use this code instead:
for value in data_dict.values():
if value['name'] in data_dict:
data_dict[value['name']].update(value)
else:
data_dict[value['name']] = value
Your data_dict_origin has numbers as keys and dicts as values (which technically makes it a sparse array of dicts). The "name" key exists in those dicts, not in your data_dict.