I'm looking to delete all objects from some JSON data if it is missing the key or value.
Here is a snippet of the JSON data:
[
{
"cacheId": "eO8MDieauGIJ",
"pagemap": {}
},
{
"cacheId": "AWYYu9XQnuwJ",
"pagemap": {
"cse_image": [
{
"src": "https://someimage.png"
}
]
}
},
{
"cacheId": "AWYYu9XQnuwJ",
"pagemap": {
"cse_image": [
{
}
]
}
}
]
I'm looking to delete the 1st and 3rd object in the data because the 1st object has an empty ['pagemap'] and the 3rd object has an empty ['pagemap']['cse_image']
Here is what I've tried so far without any luck:
for result in data[:]:
if result['pagemap']['cse_image'] == []:
data.remove(result)
for result in data[:]:
if result['pagemap'] == None:
data.remove(result)
for result in data[:]:
if len(result['pagemap']) == 0:
data.remove(result)
Thanks for the help!
Two things:
You don't want to remove elements from a list while iterating over them -- the memory you're removing is shifting as you're accessing it.
The third object has a nonempty ['pagemap']['cse_image']. Its value is a one-element list containing an empty dictionary. You need to index into the list to check whether or not the inner dictionary is empty.
With these two points in mind, here is an approach using filter() that also leverages the fact that empty data structures have falsy values:
result = list(filter(lambda x: x['pagemap'] and x['pagemap']['cse_image'] and x['pagemap']['cse_image'][0], data))
print(result)
If that data structure remains consistent, you can do it with a list comprehension.
[e for e in d if e["pagemap"] and e["pagemap"]["cse_image"] and any(e["pagemap"]["cse_image"])]
produces:
[{'cacheId': 'AWYYu9XQnuwJ', 'pagemap': {'cse_image': [{'src': 'https://someimage.png'}]}}]
Where d is your given data structure.
Related
I was looking through old posts in order to find a method of changing values in a dictionary by iterating through the items.
dictionary = {
1: [
{
"id": "1234",
"cow": "parts/sizes/lakes"
},
{
"id": "5151",
"cow": "minors/parts"
}
]}
def fetchanswers():
for item in dictionary[1]:
yield(item["id"], item["cow"])
for a, b in fetchanswers():
k = {}
k["id"] = a
k["cow"] = b.replace("parts", a)
My understanding is that yield returns the two items from either object in the dictionary and the for loop creates a new dictionary and appends the values obtained from fetchanswers() and parts is replaced by id.
I don't understand how k["id"] can be referred to when the dictionary is empty.
a method of changing values in a dictionary
Your values are strings. Strings are immutable, so you need to overwrite the dictionary using existing keys
You don't need another dictionary for this
# replace "parts" text value with the value of the id key
for item in list_of_dicts:
item["cow"] = item["cow"].replace("parts", str(item["id"]))
how k["id"] can be referred to
It's not a referral when there's an equal sign afterwards. It's an assignment
I'm having a JSON with nested values. I need to remove the key of the nested field and need to keep the values as plain JSON.
JSON(Structure of my JSON)
[
{
"id":"101",
"name":"User1",
"place":{
"city":"City1",
"district":"District1",
"state":"State1",
"country":"Country1"
},
"access":[{"status":"available"}]
}
]
I need to get the JSON output as:
Expected Output:
[
{
"id":"101",
"name":"User1",
"city":"City1",
"district":"District1",
"state":"State1",
"country":"Country1"
"access":[{"status":"available"}]
}
]
What i need is:
I need to parse the JSON
Get the Placefield out of the JSON
Remove the key and brackets and append the values to existing
Python
for i in range(0,len(json_data)):
place_data = json_data[i]['place']
print(type(place_data)) #dict
del place_data['place']
Any approach to get the expected output in python.?
One way to accomplish this could be by
for i in json_data:
i.update(i.pop("place"))
Another way to accomplish this with multiple "keys" updated...
This would only work for a single nested level as described in the original question
def expand(array):
flatten = list()
for obj in array:
temp = {}
for key, value in obj.items():
if isinstance(value, dict):
temp.update(value)
else:
temp.update({key:value})
flatten.append(temp)
return flatten
I'm new to Python, trying to gather data from a json file that consists of a list that contains info inside dictionaries as follows. How do I extract the "count" data from this? (Without using list comprehension)
{
"stats":[
{
"name":"Ron",
"count":98
},
{
"name":"Sandy",
"count":89
},
{
"name":"Sam",
"count":77
}
]
}
Index the list using the stats key then iterate through it
data = {
"stats":[
{
"name":"Ron",
"count":98
},
{
"name":"Sandy",
"count":89
},
{
"name":"Sam",
"count":77
}
]
}
for stat in data['stats']:
count = stat['count']
Consider the dictionary data stored in a variable source.
source = {
"stats":[
{
"name":"Ron",
"count":98
},
{
"name":"Sandy",
"count":89
},
{
"name":"Sam",
"count":77
}
]
}
Now to access the count field inside of "stats" we use indexing.
For example, to view the count of "Ron" you would write:
print(source['stats'][0]['count'])
This will result in 98
Similarly, for "Sam" it will be
print(source['stats'][2]['count'])
And the result will be 77
In short, we first index the key of dictionary, then the array position and then provide the filed from array of which you want the data.
I hope it helped.
Simply append all those values to do calculations:
count_values = []
for dic in data['stats']:
count_values.append(dic['count'])
# Do anything with count_values
print(count_values)
According to the Zen of Python, "Simple is better than complex."
Thus, list comprehension is actually the best way to extract the information you need and still have it available for further processing (in the form of a list of count values).
d = <your dict-list>
count_data_list = [ x['count'] for x in d['stats'] ]
If not, and your intention is to process the "count" data as it is extracted, I'd suggest a for-loop:
d = <your dict-list>
for x in d['stats']:
count_data = x['count']
<process "count_data">
using a map function will do that in a single line
>>> result = list(map(lambda x: x['count'], data['stats']))
[98, 89, 77]
Have a JSON file output similar to:
{
"object1": {
"json_data": "{json data information}",
"tables_data": "TABLES_DATA"
},
"object2": {
"json_data": {json data information}",
"tables_data": ""
}
}
Essentially, if there is an empty string for tables_data as shown in object2 (eg. "tables_data": ""), I want the entire object to be removed so that the output would look like:
{
"object1": {
"json_data": "{json data information}",
"tables_data": "TABLES_DATA"
}
}
What is the best way to go about doing this? Each of these objects correspond to a separate index in a list that I've appended called summary[].
To achieve this, you could iterate through the JSON dictionary and test the tables_data values, adding the objectX elements to a new dictionary if their tables_data value passes the test:
new_dict = {k: v for k, v in json_dict.items()
if v.get("tables_data", "") != ""}
If your JSON objectX is stored in a list as you say, these could be processed as follows using a list comprehension:
filtered_summary = [object_dict for object_dict in summary
if object_dict.get("tables_data", "") != ""]
Unless you have compelling reasons to do otherwise, the pythonic way to filter out a list or dict (or any iterable) is not to change it in place but to create a new filtered one. For your case this would look like
raw_data = YOUR_DICT_HERE_WHEREVER_IT_COMES_FROM
# NB : empty string have a false value in a boolean test
cleaned_data = {k:v for k, v in raw_data.items() if not v["table_data"]}
I want to store two values from JSON_file in new dict like this : {[1,2,5]:[0], [1,2,4]:[2]}
my JSON-file looks like this :
{
"index": [
{
"timestamp": "2018-04-17 17:56:25",
"src": "src",
"dst": [1,2,5],
"value": [0],
"datatype": "datatype"
},
{
"timestamp": "2018-04-17 18:00:43",
"src": "src",
"dst": [1,2,4],
"value": [2],
"datatype": "datatype"
}
]
}
I wrote this code:
with open(filename) as feedjson:
json_data = json.load(feedjson)
feedjson.close()
list_dev = {}
for i in json_data["index"]:
key = i['value']
value = i['dst']
list_dev[key] = value
print(list_dev)
I get this error:
list_dev.update({key: value})
TypeError: unhashable type: 'list'
can someone help me to fix this problem please?
This is just for understanding purposes:
Dictionary keys should be immutable as explained here. In the question, [1,2,5] is a list which are mutable(contents can be modified with methods like append,pop, push) data types. So, the only way to use the entire contents of a list as a dictionary key(highly unusual) is to convert it to an immutable data type such as a tuple or string:
new_dict = {} #initialize empty dictionary
dst = t['index'][0]['dst'] #[1,2,5]
value = t['index'][0]['value'] #[0]
new_dict[tuple(dst)] = value #new_dict key "dst" as tuple
print(new_dict)
--->{(1, 2, 5): [0]}
new_dict[str(dst)] = value #new_dict key "dst" as string
print(new_dict)
---->{'[1, 2, 5]': [0]}
value is a list -> [1] or [2] or whatever, list is mutable object so you can't hash it
you can use the element in the list like
key=i['value'][0]
or convert the list to tuple like
key=tuple(i['value'])
both objects are immutable thus can be hashed and used as a key
by the way with provide context manager so you don't need to close the file using feedjson.close(), with will do it for you