Python: How to convert json comma separated key to a dictionary - python-3.x

I have a JSON in below format:
{
'166, 175': 't2',
'479': 't3'
}
I want to convert this to a map:
166: 't2'
175: 't2'
479: 't3'

src = {
'166, 175': 't2',
'479': 't3'
}
res = {}
for k, v in src.items():
for i in k.split(', '):
res[int(i)] = v
print(res)

You can use some dictionary comprehension here:
{
int(k): v
for ks, v in data.items()
for k in ks.split(',')
}
For the sample data, this gives us:
>>> {
... int(k): v
... for ks, v in data.items()
... for k in ks.split(',')
... }
{166: 't2', 175: 't2', 479: 't3'}

Bit complicated though
src = {
'166, 175': 't2',
'479': 't3'
}
output = dict(reduce(lambda a, b: a + b, map(lambda b:zip(b.split(', '), [a[b]] * len(b.split(', '))), src)))

Related

convert list of dictionary values in to list of values

Hi all below is my list of dictionary
a=[{'Name': 'dhaya', 'Place': 'pune', 'Designation': 'fleetEngineer'},
{'Name': 'rishi', 'Place': 'maharastra', 'Designation': 'Sr.Manager'}]
iam expecting output like this
a={"Name":["dhaya","rishi],"Place":["pune","maharastra"],Designation:["fleetEngineer","Sr.Manager"]
"}
can any one assist
new_dict is the answer to the question you posted. Its the smallest and simplest.
b = list(a[0].keys())
new_dict = {}
for x in b:
new_dict[x] = [l[x] for l in a]
print('My expected dictionary',new_dict)
One can use nested for loops for this:
inputList = [{'Name': 'dhaya', 'Place': 'pune', 'Designation': 'fleetEngineer'}, {
'Name': 'rishi', 'Place': 'maharastra', 'Designation': 'Sr.Manager'}]
outputDict = {}
for origDict in inputList:
for key, val in origDict.items():
if key in outputDict:
outputDict[key].append(val)
else:
outputDict[key] = [val]
print(outputDict)
a=[{'Name': 'dhaya', 'Place': 'pune', 'Designation': 'fleetEngineer'}, {'Name': 'rishi', 'Place': 'maharastra', 'Designation': 'Sr.Manager'}]
Name = []
Place = []
Designation = []
for ele in a:
Name.append(ele["Name"])
Place.append(ele["Place"])
Designation.append(ele["Designation"])
new_a = {}
new_a['Name'] = Name
new_a['Place'] = Place
new_a["pune"] = Designation
print(new_a)

Check for multiple kv in a dictonary with a twist

I have a search list of dicts that I need to check if exist in another source dict.
source_dict = { 'a':'1', 'blue':'yes', 'c':'3' }
search_list = [ {'a':'1', 'b':'2'}, {'blue': 'yes'} ]
The items in the list all need to be checked however, we need a AND for all items in the same dict. OR between dicts in the list.
How would I start to tackle this problem?
You can use any and all:
>>> # the `OR` (`any`) of the `AND`s (`all`s) for each dict
>>> any(all(k in source_dict and source_dict[k] == v for k, v in d.items()) for d in search_list)
True
>>> # the `AND`s (`all`s) for each dict
>>> [all(k in source_dict and source_dict[k] == v for k, v in d.items()) for d in search_list]
[False, True]
any(map(lambda x: all(map(lambda k: source_dict[k] == x[k] if k in source_dict else False, x.keys())), search_list))

Python3 - recursively replace all keys with periods in a nested dictionary

I am trying to clean up a nested dictionary before inserting it into Mongo. Some of the keys in the dict have periods in them so I need to replace them with underscores. Based on other posts I have seen I have come up with this (not working) code sample:
def get_recursively(search_dict):
new_dict = {}
for key, value in search_dict.items():
if '.' in key or ' ' in key:
new_dict[key.replace('.', '_').replace(' ', '_').lower()] = value
elif isinstance(value, dict):
results = get_recursively(value)
for key2, value2 in results.items():
new_dict[key] = dict(key2, value2)
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
more_results = get_recursively(item)
for key3, value3 in more_results.items():
new_dict[key] = dict(key3, value3)
else:
new_dict[key] = value
return new_dict
I am trying to make a new dictionary because when I tried to modify the existing dictionary I got an error about the dictionary changing during execution.
The code that is not valid (at least) is:
dict(key2, value2)
That is not valid syntax but hopefully shows my thought process at least.
Any help much appreciated.
If I understood right, is this want you meant?
def change_chars(string, chars, new_char):
new_string = string
for char in chars:
new_string = new_string.replace(char, new_char)
return new_string
def recursively_change_keys(obj, chars, new_char):
if isinstance(obj, list):
return [
recursively_change_keys(o, chars, new_char)
for o in obj
]
elif isinstance(obj, dict):
return {
change_chars(key, chars, new_char): recursively_change_keys(value, chars, new_char)
for key, value in obj.items()
}
return obj
So you just have to call it like recursively_change(search_dict, [ ".", " " ], "_")
Try:
import json
d = {
"some.key": [
{
"key.1": {"a": 1},
"key.2": 2,
"key.3": {"key.4": [3, 4, 5], "key.5": 6},
}
]
}
def transform(d):
if isinstance(d, dict):
return {k.replace(".", "_"): transform(v) for k, v in d.items()}
elif isinstance(d, list):
return [transform(v) for v in d]
else:
return d
# pretty print the dictionary:
print(json.dumps(transform(d), indent=4))
Prints:
{
"some_key": [
{
"key_1": {
"a": 1
},
"key_2": 2,
"key_3": {
"key_4": [
3,
4,
5
],
"key_5": 6
}
}
]
}

How to add currency sign to all integers in a list of nested dictionaries

Given a list of nested dictionaries how can I add the currency locale to all the integer values using the locale module. My current solution works however I could not figure out how to make it work with nested dictionaries nor does it feel pythonic.
Example input
[
{
'name':'Tom',
'total_salary': 70000,
'salary': {
'base': 65000,
'bonus': 5000
}
},
{
'name':'Andrew',
'total_salary': 50000,
'salary': {
'base': 45000,
'bonus': 5000
}
}
]
Wanted output
[
{
'name':'Tom',
'total_salary': '$70000',
'salary': {
'base': '$65000',
'bonus': '$5000'
}
},
{
'name':'Andrew',
'total_salary': '$50000',
'salary': {
'base': '$45000',
'bonus': '$5000'
}
}
]
current solution
import locale
locale.setlocale( locale.LC_ALL, 'en_CA.UTF-8' )
def add_currency_locale(_list):
new_list = []
for d in _list:
for k,v in list(d.items()):
try:
v = float(v)
new_value = locale.currency(v, grouping=True)
d[k] = new_value
except:
pass
new_list.append(d)
return new_list
Because you have the line locale.setlocale( locale.LC_ALL, 'en_CA.UTF-8' ), I think you don't want to have the local currency symbol, but want it to always be '$'. If so, here is my solution, otherwise you can easily replace the line where I set new_value. I'm using recursion to correctly handle cases when you have nested lists or dictionaries (the code you've provided seems to not work for those cases, but according to the example input and output you need this. If you don't, remove the part with instance checking and replace the line except ValueError: with except (ValueError, TypeError):). Pay attention to the notes I left in the comments
# Note: variable names with one leading underscore are "private" according to python code style.
# Use trailing underscore instead
def add_currency_locale(list_):
new_list = []
for d in list_:
# Note: no need to convert `d.items()` to list: you can iterate over the original
# object, and the conversion takes time
for k, v in d.items():
if isinstance(v, dict):
# Because `add_currency_locale` only works with arrays, make an array of one
# dictionary and then only use the first (and only) element of the returned list
d[k] = add_currency_locale([v])[0]
elif isinstance(v, list):
d[k] = add_currency_locale(v)
elif isinstance(v, (int, float)):
d[k] = f'${v}'
else:
d[k] = v
new_list.append(d)
return new_list
You can use this code to iterate through all the data elements and get the $ symbol assigned to each value.
def add_curr(dict_list):
new_lst = []
for dic in dict_list:
for k1, v1 in dic.items():
if not isinstance(v1, dict):
if isinstance(v1, (int, float)):
dic[k1] = '${}'.format(v1)
else:
dic[k1] = v1
else:
for k2,v2 in v1.items():
isinstance(v2, (int, float)):
dic[k1][k2] = '${}'.format(v2)
else:
dic[k1][k2] = v2
new_lst.append(dic)
return new_lst
add_curr(mylist)
You could decide to use the conversion part as a separate function and call it each time with a key and value
if isinstance(v1, (int, float)):
dic[k1] = '${}'.format(v1)
else:
dic[k1] = v1
This will give you the following dict:
[{'name': 'Tom',
'total_salary': '$70000',
'salary':
{'base': '$65000',
'bonus': '$5000'}},
{'name': 'Andrew',
'total_salary': '$50000',
'salary':
{'base': '$45000',
'bonus': '$5000'}}]
If you want to use the locale module:
lst = [
{
'name':'Tom',
'total_salary': 70000,
'salary': {
'base': 65000,
'bonus': 5000
}
},
{
'name':'Andrew',
'total_salary': 50000,
'salary': {
'base': 45000,
'bonus': 5000
}
}
]
import locale
locale.setlocale( locale.LC_ALL, 'en_CA.UTF-8' )
def cnvrt(dct):
for k, v in dct.items():
if isinstance(v, dict):
dct[k] = cnvrt(v)
elif isinstance(v, int) or isinstance(v, float):
dct[k] = locale.currency(v, grouping=True)
return dct
print([cnvrt(i) for i in lst])
However, that won't give you your expected output which is just a $ prepended to the value.
For that you can use.
def cnvrt(dct):
for k, v in dct.items():
if isinstance(v, dict):
dct[k] = cnvrt(v)
elif isinstance(v, int) or isinstance(v, float):
dct[k] = f'${v}'
return dct
print([cnvrt(i) for i in lst])
This works by recursively calling cnvrt if the value is a nested dict, otherwise, if it's an int or float it prepends a $. Since it's operating on the expectation of a dict object, you can use it in a nice list comprehension.
Finally, if you really want to you can handle lists with your function but IMO at this point it is doing too much.
def cnvrt(obj):
if isinstance(obj, list):
obj = [cnvrt(i) for i in obj]
elif isinstance(obj, dict):
for k, v in obj.items():
if isinstance(v, dict) or isinstance(v, list):
obj[k] = cnvrt(v)
elif isinstance(v, int) or isinstance(v, float):
obj[k] = f'${v}'
return obj
print(cnvrt(lst))
Although, it works with inner lists and dicts as well, There is a lot going on which makes it hard to follow.

Convert txt file to Dictionary in Python

I have a txt file that contain the following:
Monday, 56
Tuesday, 89
Wednesday, 57
Monday, 34
Tuesday, 31
Wednesday, 99
I need it to be converted to a dictionary:
{'Monday': [56 , 34], 'Tuesday': [89, 31], 'Wednesday': [57, 99]}
Here is the code I have so far:
d = {}
with open("test.txt") as f:
for line in f:
(key, val) = line.split()
d[str(key)] = val
print(d)
And here is the result I get from it:
{'Monday,': '56'}
{'Monday,': '56', 'Tuesday,': '89'}
{'Monday,': '56', 'Tuesday,': '89', 'Wednesday,': '57'}
{'Monday,': '34', 'Tuesday,': '89', 'Wednesday,': '57'}
{'Monday,': '34', 'Tuesday,': '31', 'Wednesday,': '57'}
{'Monday,': '34', 'Tuesday,': '31', 'Wednesday,': '99'}
Can anyone help me with this?
Thanks
d = {}
with open("test.txt") as f:
for line in f:
(key, val) = line.split()
if not key in d.keys():
d[key] = []
d[key].append(val)
print (d)
This should work.
When you split the line you can use comma as a separator. Then after splitting the line you can check the dictionary on whether it already contain the key:
(key, val) = line.split(',')
if key in d.keys:
d[str(key)].append(val)
else:
d[str(key)] = [val]
print (d)
d = {}
with open("test.txt") as f:
for line in f:
(key, val) = line.split()
if key in d:
d[str(key)].append(val)
else:
d[str(key)] = [val]
print(d)
Try to add list of value in dictionary.

Resources