parse specific data from the list using list comprehension - python

i am facing the problem which is to parse specific data from list. I have a list sth like :
response_list = [{
"Name": "Brand",
"Value": "Smart Planet",
"Source": "ItemSpecific"
},
{
"Name": "Color",
"Value": "Yellow",
"Source": "ItemSpecific"
},
{
"Name": "Type",
"Value": "Sandwich Maker",
"Source": "ItemSpecific"
},
{
"Name": "Power Source",
"Value": "Electrical",
"Source": "ItemSpecific"
}]
From the list I should get the Brand name. Every time it will come in different position.How can i get it using list comprehension.Output will be like :
new_list =[{'Brand':'Smart Planet'}]

You have a list of dicts, you want to take only the Name and the Value field of this list.
You can do:
[{item["Name"]: item["Value"]} for item in response_list]
You get:
[{'Brand': 'Smart Planet'}, {'Color': 'Yellow'}, {'Type': 'Sandwich Maker'}, {'Power Source': 'Electrical'}]
Is it what you want?
EDIT
If you only want the brand name, you need to filter:
[{"Brand": item["Value"]} for item in response_list if item["Name"] == "Brand"]

Related

Find a value in a list of dictionaries

I have the following list:
{
"id":1,
"name":"John",
"status":2,
"custom_attributes":[
{
"attribute_code":"address",
"value":"st"
},
{
"attribute_code":"city",
"value":"st"
},
{
"attribute_code":"job",
"value":"test"
}]
}
I need to get the value from the attribute_code that is equal city
I've tried this code:
if list["custom_attributes"]["attribute_code"] == "city" in list:
var = list["value"]
But this gives me the following error:
TypeError: list indices must be integers or slices, not str
What i'm doing wrong here? I've read this solution and this solution but din't understood how to access each value.
Another solution, using next():
dct = {
"id": 1,
"name": "John",
"status": 2,
"custom_attributes": [
{"attribute_code": "address", "value": "st"},
{"attribute_code": "city", "value": "st"},
{"attribute_code": "job", "value": "test"},
],
}
val = next(d["value"] for d in dct["custom_attributes"] if d["attribute_code"] == "city")
print(val)
Prints:
st
Your data is a dict not a list.
You need to scan the attributes according the criteria you mentioned.
See below:
data = {
"id": 1,
"name": "John",
"status": 2,
"custom_attributes": [
{
"attribute_code": "address",
"value": "st"
},
{
"attribute_code": "city",
"value": "st"
},
{
"attribute_code": "job",
"value": "test"
}]
}
for attr in data['custom_attributes']:
if attr['attribute_code'] == 'city':
print(attr['value'])
break
output
st

How to get output into dictionary format from given data?

I have a field where value is as below
b = [
{
"category": "Engineer",
"name": "Anthony Test",
"id": 219
},
{
"category": "Engineer",
"name": "Pete Junior",
"id": 220
}
]
I would like to get the result in below format where I want to eliminate category and create a dictionary with id and name
result = {'219': 'Anthony Test', '220': 'Pete Junior'}
You can use dictionary comprehension
{i['id']: i['name'] for i in b}

Very nested JSON with optional fields into pandas dataframe

I have a JSON with the following structure. I want to extract some data to different lists so that I will be able to transform them into a pandas dataframe.
{
"ratings": {
"like": {
"average": null,
"counts": {
"1": {
"total": 0,
"users": []
}
}
}
},
"sharefile_vault_url": null,
"last_event_on": "2021-02-03 00:00:01",
],
"fields": [
{
"type": "text",
"field_id": 130987800,
"label": "Name and Surname",
"values": [
{
"value": "John Smith"
}
],
{
"type": "category",
"field_id": 139057651,
"label": "Gender",
"values": [
{
"value": {
"status": "active",
"text": "Male",
"id": 1,
"color": "DCEBD8"
}
}
],
{
"type": "category",
"field_id": 151333010,
"label": "Field of Studies",
"values": [
{
"value": {
"status": "active",
"text": "Languages",
"id": 3,
"color": "DCEBD8"
}
}
],
}
}
For example, I create a list
names = []
where if "label" in the "fields" list is "Name and Surname" I append ["values"][0]["value"] so names now contains "John Smith". I do exactly the same for the "Gender" label and append the value to the list genders.
The above dictionary is contained in a list of dictionaries so I just have to loop though the list and extract the relevant fields like this:
names = []
genders = []
for r in range(len(users)):
for i in range(len(users[r].json()["items"])):
for field in users[r].json()["items"][i]["fields"]:
if field["label"] == "Name and Surname":
names.append(field["values"][0]["value"])
elif field["label"] == "Gender":
genders.append(field["values"][0]["value"]["text"])
else:
# Something else
where users is a list of responses from the API, each JSON of which has the items is a list of dictionaries where I can find the field key which has as the value a list of dictionaries of different fields (like Name and Surname and Gender).
The problem is that the dictionary with "label: Field of Studies" is optional and is not always present in the list of fields.
How can I manage to check for its presence, and if so append its value to a list, and None otherwise?
To me it seems that the data you have is not valid JSON. However if I were you I would try using pandas.json_normalize. According to the documentation this function will put None if it encounters an object with a label not inside it.

Return nested JSON item that has multiple instances

So i am able to return almost all data, except i am not able to capture something like this:
"expand": "schema"
"issues": [
{
"expand": "<>",
"id": "<>",
"self": "<>",
"key": "<>",
"fields": {
"components": [
{
"self": "<>",
"id": "1",
"name": "<>",
"description": "<>"
}
]
}
},
{
"expand": "<>",
"id": "<>",
"self": "<>",
"key": "<>",
"fields": {
"components": [
{
"self": "<>",
"id": "<>",
"name": "<>"
}
]
}
},
I want to return a list that contains both of the 'name's for 'components', i have tried using:
list((item['fields']['components']['name']) for item in data['issues'])
but i get a type error saying TypeError: list indices must be integers or slices, not str when i try to Print() the above line of code
Also, if i could get some explanation of what this type error means, and what "list" is trying to do that means that it is not a "str" that would be appreciated
EDIT:
url = '<url>'
r = http.request('GET', url, headers=headers)
data = json.loads(r.data.decode('utf-8'))
print([d['name'] for d in item['fields']['components']] for item in data['issues'])
As the commenter points out you're treating the list like a dictionary, instead this will select the name fields from the dictionaries in the list:
list((item['fields']['components'][i]['name'] for i, v in enumerate(item['fields']['components'])))
Or simply:
[d['name'] for d in item['fields']['components']]
You'd then need to apply the above to all the items in the iterable.
EDIT: Full solution to just print the name fields, assuming that "issues" is a key in some larger dictionary structure:
for list_item in data["issues"]: # issues is a list, so iterate through list items
for dct in list_item["fields"]["components"]: # each list_item is a dictionary
print(dct["name"]) # name is a field in each dictionary

Find a value in JSON using Python

I’ve previously succeeded in parsing data from a JSON file, but now I’m facing a problem with the function I want to achieve. I have a list of names, identification numbers and birthdate in a JSON. What I want to get in Python is to be able to let a user input a name and retrieve his identification number and the birthdate (if present).
This is my JSON example file:
[
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": null
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
To be clear, I want to input "V410Z8" and get his name and his birthdate.
I tried to write some code in Python but I only succeed in searching for “id_number” and not for what is inside “id_number” for example "V410Z8".
#!/usr/bin/python
# -*- coding: utf-8 -*-
import json
database = "example.json"
data = json.loads(open(database).read())
id_number = data[0]["id_number"]
print id_number
Thank you for your support, guys :)
You have to iterate over the list of dictionaries and search for the one with the given id_number. Once you find it you can print the rest of its data and break, assuming id_number is unique.
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
for i in data:
if i['id_number'] == 'V410Z8':
print(i['birthdate'])
print(i['name'])
break
If you have control over the data structure, a more efficient way would be to use the id_number as a key (again, assuming id_number is unique):
data = { "SA4784" : {"name": "Mark", "birthdate": None},
"V410Z8" : { "name": "Vincent", "birthdate": "15/02/1989"},
"CZ1094" : {"name": "Paul", "birthdate": "27/09/1994"}
}
Then all you need to do is try to access it directly:
try:
print(data["V410Z8"]["name"])
except KeyError:
print("ID doesn't exist")
>> "Vincent"
Using lamda in Python
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
Using Lambda and filter
print(list(filter(lambda x:x["id_number"]=="CZ1094",data)))
Output
[{'id_number': 'CZ1094', 'name': 'Paul', 'birthdate': '27/09/1994'}]
You can use list comprehension:
Given
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
to get the list item(s) with id_number equal to "V410Z8" you may use:
result = [x for x in data if x["id_number"]=="V410Z8"]
result will contain:
[{'id_number': 'V410Z8', 'name': 'Vincent', 'birthdate': '15/02/1989'}]
In case the if condition is not satisfied, result will contain an empty list: []
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "14/02/1989"
},
{
"id_number": "CZ1093",
"name": "Paul",
"birthdate": "26/09/1994"
}
]
list(map(lambda x:x if x["id_number"]=="cz1093" ,data)
Output should be
[{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "26/09/1994"
}]
If you are only interested in one or a subset of total results, then I'd suggest a generator function as the fastest solution, since it will not unnecessarily iterate over every item regardless, and is more memory efficient:
def gen_func(data, search_term):
for i in data:
if i['id_number'] == search_term:
yield i
You can then run the following to retrieve results for CZ1094:
foo = gen_func(data, 'CZ1094')
next(foo)
{'id_number': 'CZ1094', 'name': 'Paul', 'birthdate': '27/09/1994'}
NB: You'll need to handle StopIteration at end of iterable.

Categories