Create dict from string in Python - python

In my Python program, I have a string of format:
'name': 'Salman','age': '25', 'access': 'R', 'id': '00125'
I want to convert it to type dict so that I can query like dict["name"] to get "Salman" printed.

Use ast.literal_eval:
import ast
mystr = "'name': 'Salman','age': '25', 'access': 'R', 'id': '00125'"
d = ast.literal_eval('{'+mystr+'}')
# {'access': 'R', 'age': '25', 'id': '00125', 'name': 'Salman'}
d['access'] # 'R'

I think this is a neat solution using comprehensions
s = "'name': 'Salman','age': '25', 'access': 'R', 'id': '00125'"
d = dict([i.strip().replace("'", "") for i in kv.split(':')] for kv in s.split(","))
# d == {'access': 'R', 'age': '25', 'id': '00125', 'name': 'Salman'}

first split the string by ":" and "," and store it in a list.
then iterate from 0 to len(list)-2: mydict[list[i]] = list[i+1]

Related

Combine some items in list [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 12 months ago.
Improve this question
I have list like this,
arr = [{"type":"A","name":"1"},
{"type":"B","name":"2"},
{"type":"B","name":"3"},
{"type":"C","name":"4"},
{"type":"B","name":"5"},
{"type":"B","name":"6"},
{"type":"D","name":"7"},
{"type":"B","name":"8"},
{"type":"B","name":"9"},]]
I want to combine type B like this below
Adding pages key
[{"type":"A","name":"1"},
{"type":"B","pages":[
{"type":"B","name":"2"},
{"type":"B","name":"3"}]},
{"type":"C","name":"4"},
{"type":"B","pages":[
{"type":"B","name":"5"},
{"type":"B","name":"6"}
]},
{"type":"D","name":"7"},
{"type":"B","pages":[
{"type":"B","name":"8"},
{"type":"B","name":"9"}
]}
]
I try to do this with loop,
However, still struggling..
Please give me some ideas.
result = []
first = False
for i in arr:
if i['type'] == "B":
if first == False:
first = True
i['pages'] = []
i['pages'].append(i)
else:
i['pages'].append(i)
else:
result.append(i)
flg = False
print(result)
Here's a solution using itertools.groupby:
from itertools import groupby
result = []
for key, group in groupby(arr, key=lambda x: x['type']):
group = list(group)
if len(group) > 1:
result.append({'type': key, 'pages': group})
else:
result.append(group[0])
from pprint import pprint
pprint(result)
Output:
[{'name': '1', 'type': 'A'},
{'pages': [{'name': '2', 'type': 'B'}, {'name': '3', 'type': 'B'}],
'type': 'B'},
{'name': '4', 'type': 'C'},
{'pages': [{'name': '5', 'type': 'B'}, {'name': '6', 'type': 'B'}],
'type': 'B'},
{'name': '7', 'type': 'D'},
{'pages': [{'name': '8', 'type': 'B'}, {'name': '9', 'type': 'B'}],
'type': 'B'}]

how to use nested dictionary in python which return user defined variable

I am trying to fetch value of time if found in people it should print time otherwise without time
Below is code which I am trying to test:
import datetime
people = {1: {'time': '', 'age': '27', 'sex': 'Male'},
2: {'time': '', 'age': '22', 'sex': 'Female'}}
time = datetime.datetime.now()
for time in people.items():
if time in people.items():
print(people,"true");
else:
print(people,"false");
The output is :
{1: {'age': '27', 'sex': 'Male', 'time': ''}, 2: {'age': '22', 'sex': 'Female', 'time': ''}} true
{1: {'age': '27', 'sex': 'Male', 'time': ''}, 2: {'age': '22', 'sex': 'Female', 'time': ''}} true
I want it to display the value of current timestamp value in time.
Desired output:
{1: {'age': '27', 'sex': 'Male', 'time': '2021-06-17T05:42:32.204965'}, 2: {'age': '22', 'sex': 'Female', 'time': '2021-06-17T05:42:32.204965'}} true
Refrence:
{
"id": "urn:ngsi-ld:Device:filling001",
"type": "FillingSensor",
"filling": {
"type": "Property",
"value": 0.94,
"unitCode": "C62",
**"time": "2021-01-28T12:33:10.000Z"**
},
"time_index": "2021-01-28T12:33:20.476"
}
What i am doing wrong here. help on this will be great?
There are several problems with your code :
You use the same variable time with time = datetime.datetime.now() and for time in people.items() so the second will overwrite the first one value.
people.items() returns a tuple of key, value elements, ie: (1, {...}) so you cannot compare time with (key, value).
Using in operator for this seems quite wrong to me, I would try something like below.
.
time = datetime.datetime.now()
for key, val in people.items():
print({key:val}, "true" if val.get("time") == time else "false")
You need to initialize time as datetime.datetime.now() before the dictionary initialization, and then replace the empty quotes with time.

Iterating through a nested dictionary to check if a particular value is all numerical letters

the following is a subset of a really large nested dictionary that I have:
{
'1': {'Name': 'Katherine Watson',
'Age': '1',
'Height': '150'},
'2': {'Name': 'Emilia Li',
'Age': '56',
'Height': '175'},
'3': {'Name': 'Dorothy Johnson',
'Age': '29',
'Height': '162'},
'4': {'Name': 'Alexandar Knight',
'Age': '14',
'Height': '164r'}
}
I'm having trouble figuring out how to write a function that will iterate through the specific key ('Height'), which then returns the corresponding value if it's all numerical numbers or None otherwise.
E.g. the dictionary with ID'1' should return '150' for the height. But the dictionary with ID'4' should return None for the height.
Here's a code I've written but it only returns '150' instead of iterating through all the IDs and returning '150' '175' '162' 'None'.
data = {
'1': {'Name': 'Katherine Watson',
'Age': '1',
'Height': '150'},
'2': {'Name': 'Emilia Li',
'Age': '56',
'Height': '175'},
'3': {'Name': 'Dorothy Johnson',
'Age': '29',
'Height': '162'},
'4': {'Name': 'Alexandar Knight',
'Age': '14',
'Height': '164r'}
}
def person_height(height):
for some_id, info in data.items():
if info['Height'].isnumeric():
return info['Height']
else:
return None
Use isdigit
data = {
'1': {'Name': 'Katherine Watson',
'Age': '1',
'Height': '150'},
'2': {'Name': 'Emilia Li',
'Age': '56',
'Height': '175'},
'3': {'Name': 'Dorothy Johnson',
'Age': '29',
'Height': '162'},
'4': {'Name': 'Alexandar Knight',
'Age': '14',
'Height': '164r'}
}
def person_height(height):
if height.isdigit():
return height
for some_id, info in data.items():
print("\nID:", some_id)
print("Height:", person_height(info['Height']))
Output:
ID: 1
Height: 150
ID: 2
Height: 175
ID: 3
Height: 162
ID: 4
Height: None
You could also do this with a list comprehension.
def get_heights(data):
return [int(person['Height'])
if person['Height'].isdigit()
else None
for person in data.values()]
print(get_heights(data))
Running it with your sample data outputs:
[150, 175, 162, None]
Since you're not using the IDs, you can use .values() instead of .items(). And in your code, you named the argument height but then refer to data in the function body. This means that it doesn't matter what you supply as the argument; the code only works because it's referring back to the globally defined variable, which happens to have the same name.
I've also converted the heights to integers, even though you didn't specifically request that.
Your code is fine actually but return will break the loop immediately and return the first result only so just turn your return to print() will do the work.
Another way is save the result to a list first and read them later:
data = {
'1': {'Name': 'Katherine Watson',
'Age': '1',
'Height': '150'},
'2': {'Name': 'Emilia Li',
'Age': '56',
'Height': '175'},
'3': {'Name': 'Dorothy Johnson',
'Age': '29',
'Height': '162'},
'4': {'Name': 'Alexandar Knight',
'Age': '14',
'Height': '164r'}
}
def person_height(data):
height_list = []
for some_id, info in data.items():
if info['Height'].isnumeric():
height_list.append(info['Height'])
else:
height_list.append(None)
return height_list
for height in person_height(data):
print(height)
Output:
150
175
162
None
In order to store your results in a "clean" dictionary, you will need as many nested loops as nested dictionaries you have. So:
def check_height(your_dict):
new_clean_dict = {}
for a, b in your_dict.items():
for e, f in b.items():
if e == 'Height' and f.isdigit():
new_clean_dict[a] = {'Height': f}
else:
new_clean_dict[a] = {'Height': None}
return new_clean_dict
This will produce a new dictionary with the same root key and with a value for each key that is a nested dictionary with only the key Height.
In order to get the results:
new_clean_dict = check_height(your_dict)

Compare values in list of dicts in Python

I'm a newbie in Python. I have a list of members and a list of meetings (containing the member id):
memberList = [{'id': '1', 'name': 'Joe'},
{'id': '2', 'name': 'Jason'},
{'id': '3', 'name': 'Billy'}]
meetingList = [{'meetingId': '20', 'hostId' : '1'},
{'meetingId': '21', 'hostId' : '1'},
{'meetingId': '22', 'hostId' : '2'},
{'meetingId': '23', 'hostId' : '2'}]
Where the id of the member and the hostId of meeting is the same value.
Result: a list of member ids which has no meetings ['3'] or the list of dicts [{'id': '3', 'name': 'Billy'}]
What's the best and most readable way to do it?
You could build a set of hosts and then use a list comprehension to filter out the members:
member_list = [{'id': '1', 'name': 'Joe'},
{'id': '2', 'name': 'Jason'},
{'id': '3', 'name': 'Billy'}]
meeting_list = [{'meetingId': '20', 'hostId': '1'},
{'meetingId': '21', 'hostId': '1'},
{'meetingId': '22', 'hostId': '2'},
{'meetingId': '23', 'hostId': '2'}]
# create a set of hosts
hosts = set(meeting['hostId'] for meeting in meeting_list) # or { meeting['hostId'] for meeting in meeting_list }
# filter out the members that are in hosts
res = [member['id'] for member in member_list if member['id'] not in hosts]
print(res)
Output
[{'id': '3', 'name': 'Billy'}]
For the id only output, do:
res = [member['id'] for member in member_list if member['id'] not in hosts]
print(res)
Output
['3']
I'd extract out the id's from both lists of dictionaries and compare them directly.
First I'm just rewriting your list variables to assign them with =.
Using : won't save the variable.
memberList = [{'id': '1', 'name': 'Joe'},
{'id': '2', 'name': 'Jason'},
{'id': '3', 'name': 'Billy'}]
meetingList = [{'meetingId': '20', 'hostId' : '1'},
{'meetingId': '21', 'hostId' : '1'},
{'meetingId': '22', 'hostId' : '2'},
{'meetingId': '23', 'hostId' : '2'}]
Then use list comprehension to extract out the id's from each list of dicts.
member_id_list = [i["id"] for i in memberList]
meeting_hostid_list = [i["hostId"] for i in meetingList]
You could also use list comprehension here but if you aren't familiar with it, this for loop and if logic will print out any member id who isn't a host.
for i in member_id_list:
if i not in meeting_hostid_list:
print(i)
>> 3

Creating a dictionary from a json list of arrays

I'm trying to create a dictionary of specific key values from a list of dictionaries. I believe my code is not flattening out the dictionaries when i put in chunkdata.extend(pythondict[0][1][2], chunkdata will return with the whole 1st 2nd and 3rd dictionaries where i want something like the "name" key pair for all the dictionaries that return in the response.
chunkdata = []
for chunk in chunklist:
url3 = "some URL"
headers = {'accept': 'application/json',
response = requests.request("GET", url3, headers=headers)
time.sleep(5)
print(response.text)
pythondict = json.loads(response.text)
print(pythondict)
chunkdata.extend(pythondict['name']['age']['date']
pythondict output
[{'data': {'name': 'jon', 'age': '30', 'date': '2020-01-05', 'time': '1', 'color': 'blue'}, {'data': {'name': 'phil', 'age': '33', 'date': '2020-01-05', 'time': '1', 'color': 'blue'}, {'data': {'name': 'ted', 'age': '25', 'date': '2020-01-05', 'time':'1', 'color': 'blue'}]
Traceback (most recent call last):
File line 84, in <module>
chunkdata.extend(pythondict['name']['age']['date']
TypeError: list indices must be integers or slices, not str
Use requests.json() for parsing. It is more reliable and accurate.
Note: Response header MUST contain Content-Type: application/json in the header in order for .json() method to work
I figured out that the json format you get is not right here. I was not able to make out the necessity of the 'data:' prior to each element.
It would be better to modify it in the following form:
python_dict=[{'name': 'jon', 'age': '30', 'date': '2020-01-05', 'time': '1', 'color': 'blue'}, {'name': 'phil', 'age': '33', 'date': '2020-01-05', 'time': '1', 'color': 'blue'}, {'name': 'ted', 'age': '25', 'date': '2020-01-05', 'time':'1', 'color': 'blue'}]
Modify the relevant part of the code as follows:
chunkdata=[]
for x in range(len(python_dict)):
temp_list=[python_dict[x]['name'],python_dict[x]['age'],python_dict[x]['date'],python_dict[x]['time'],python_dict[x]['color']]
chunkdata.append(temp_list)
print(chunkdata)
chunkdata will be a list of lists that you can keep appending into. The output for chunkdata is as follows:
[['jon', '30', '2020-01-05', '1', 'blue'], ['phil', '33',
'2020-01-05', '1', 'blue'], ['ted', '25', '2020-01-05', '1', 'blue']]

Categories