"fwt-master2": {
"ipv4": {
"rtr": {
"ip": "1.2.3.4",
"net": "3.4.5.6",
"netlen": "24",
"netmask": "255.255.255.0",
"broadcast": "7.8.9.1"
}
}
I am trying to get the ip value from this JSON file without specifying the values of each element (without using fwt-maser2[ipv4][rtr][ip]).
using the .values() method (.values()[0].values()[0].values()[0]`)
I am getting the netlen value (24) instead of the ip values which is actually the first element.
why is such thing happening?
I think use of nested code to find key value is the best way ...this way you just search if "broadcast" key in dict then print its value
Try something rom here: find all occurances of a key
If you only know that the target key is "ip", then you can use recursion:
s = {"fwt-master2": {
"ipv4": {
"rtr": {
"ip": "1.2.3.4",
"net": "3.4.5.6",
"netlen": "24",
"netmask": "255.255.255.0",
"broadcast": "7.8.9.1"
}
}
}
}
def get_ip(d):
return [i for c in filter(None, [b if a == 'ip' else get_ip(b) if isinstance(b, dict) else None for a, b in d.items()]) for i in c]
print(''.join(get_ip(s)))
Output:
1.2.3.4
I decided to go through your dictionary and found that its incomplete !!!
your dictionary :
"fwt-master2": {
"ipv4": {
"rtr": {
"ip": "1.2.3.4",
"net": "3.4.5.6",
"netlen": "24",
"netmask": "255.255.255.0",
"broadcast": "7.8.9.1"
}
}
Actually it should be like : Added missing curly braces ... first and last two..
{"fwt-master2": { "ipv4": { "rtr": { "ip": "1.2.3.4", "net": "3.4.5.6", "netlen": "24", "netmask": "255.255.255.0", "broadcast": "7.8.9.1" }}}}
Well it happens ... so Amusing above updated one is the actual dictionary so here is how you can achieve your goal:
>>> d = {"fwt-master2": { "ipv4": { "rtr": { "ip": "1.2.3.4", "net": "3.4.5.6", "netlen": "24", "netmask": "255.255.255.0", "broadcast": "7.8.9.1" }}}}
>>> obj = []
>>> obj.append(d)
>>> obj
[{'fwt-master2': {'ipv4': {'rtr': {'net': '3.4.5.6', 'netlen': '24', 'ip': '1.2.3.4', 'netmask': '255.255.255.0', 'broadcast': '7.8.9.1'}}}}]
>>> key_list = ['netmask', 'broadcast', 'ip', 'net']
>>> def recursive_items(dictionary):
... for key, value in dictionary.items():
... if type(value) is dict:
... yield from recursive_items(value)
... else:
... yield (key, value)
...
>>> def find_key(obj):
... for e in obj:
... for key, value in recursive_items(e):
... if key in key_list:
... print(key, value)
... for key, value in recursive_items(e):
... if key in key_list and value == 0:
... print(double_quote(key),":", value)
...
>>> find_key(obj)
net 3.4.5.6
ip 1.2.3.4
netmask 255.255.255.0
broadcast 7.8.9.1
Have Fun
Related
I have some json that I would like to transform from this:
[
{
"name":"field1",
"intValue":"1"
},
{
"name":"field2",
"intValue":"2"
},
...
{
"name":"fieldN",
"intValue":"N"
}
]
into this:
{ "field1" : "1",
"field2" : "2",
...
"fieldN" : "N",
}
For each pair, I need to change the value of the name field to a key, and the values of the intValue field to a value. This doesn't seem like flattening or denormalizing. Are there any tools that might do this out-of-the-box, or will this have to be brute-forced? What's the most pythonic way to accomplish this?
parameters = [ # assuming this is loaded already
{
"name":"field1",
"intValue":"1"
},
{
"name":"field2",
"intValue":"2"
},
{
"name":"fieldN",
"intValue":"N"
}
]
field_int_map = dict()
for p in parameters:
field_int_map[p['name']] = p['intValue']
yields {'field1': '1', 'field2': '2', 'fieldN': 'N'}
or as a dict comprehension
field_int_map = {p['name']:p['intValue'] for p in parameters}
This works to combine the name attribute with the intValue as key:value pairs, but the result is a dictionary instead of the original input type which was a list.
Use dictionary comprehension:
json_dct = {"parameters":
[
{
"name":"field1",
"intValue":"1"
},
{
"name":"field2",
"intValue":"2"
},
{
"name":"fieldN",
"intValue":"N"
}
]}
dct = {d["name"]: d["intValue"] for d in json_dct["parameters"]}
print(dct)
# {'field1': '1', 'field2': '2', 'fieldN': 'N'}
I have the below python dictionary stored as dictPython
{
"paging": {"count": 10, "start": 0, "links": []},
"elements": [
{
"organizationalTarget~": {
"vanityName": "vv",
"localizedName": "ViV",
"name": {
"localized": {"en_US": "ViV"},
"preferredLocale": {"country": "US", "language": "en"},
},
"primaryOrganizationType": "NONE",
"locations": [],
"id": 109,
},
"role": "ADMINISTRATOR",
},
],
}
I need to get the values of vanityName, localizedName and also the values from name->localized and name->preferredLocale.
I tried dictPython.keys() and it returned dict_keys(['paging', 'elements']).
Also I tried dictPython.values() and it returned me what is inside of the parenthesis({}).
I need to get [vv, ViV, ViV, US, en]
I am writing this in a form of answer, so I can get to explain it better without the comments characters limit
a dict in python is an efficient key/value structure or data type
for example dict_ = {'key1': 'val1', 'key2': 'val2'} to fetch key1 we can do it in 2 different ways
dict_.get(key1) this returns the value of the key in this case val1, this method has its advantage, that if the key1 is wrong or not found it returns None so no exceptions are raised. You can do dict_.get(key1, 'returning this string if the key is not found')
dict_['key1'] doing the same .get(...) but will raise a KeyError if the key is not found
So to answer your question after this introduction,
a dict can be thought of as nested dictionaries and/or objects inside of one another
to get your values you can do the following
# Fetch base dictionary to make code more readable
base_dict = dict_["elements"][0]["organizationalTarget~"]
# fetch name_dict following the same approach as above code
name_dict = base_dict["name"]
localized_dict = name_dict["localized"]
preferred_locale_dict = name_dict ["preferredLocale"]
so now we fetch all of the wanted data in their corresponding locations from your given dictionary, now to print the results, we can do the following
results_arr = []
for key1, key2 in zip(localized_dict, preferredLocale_dict):
results_arr.append(localized_dict.get(key1))
results_arr.append(preferred_locale_dict.get(key2))
print(results_arr)
What about:
dic = {
"paging": {"count": 10, "start": 0, "links": []},
"elements": [
{
"organizationalTarget~": {
"vanityName": "vv",
"localizedName": "ViV",
"name": {
"localized": {"en_US": "ViV"},
"preferredLocale": {"country": "US", "language": "en"},
},
"primaryOrganizationType": "NONE",
"locations": [],
"id": 109,
},
"role": "ADMINISTRATOR",
},
],
}
base = dic["elements"][0]["organizationalTarget~"]
c = base["name"]["localized"]
d = base["name"]["preferredLocale"]
output = [base["vanityName"], base["localizedName"]]
output.extend([c[key] for key in c])
output.extend([d[key] for key in d])
print(output)
outputs:
['vv', 'ViV', 'ViV', 'US', 'en']
So something like this?
[[x['organizationalTarget~']['vanityName'],
x['organizationalTarget~']['localizedName'],
x['organizationalTarget~']['name']['localized']['en_US'],
x['organizationalTarget~']['name']['preferredLocale']['country'],
x['organizationalTarget~']['name']['preferredLocale']['language'],
] for x in s['elements']]
Re-edited to make more clear and simple
For below data
[
{
"name": "name1",
"a_id": "12345",
"b_id": "0d687c94c5f4"
},
{
"name": "name2",
"a_id": "67890",
"b_id": "0d687c94c5f4"
},
{
"name": "name3",
"a_id": "23857",
"b_id": "9ec34be3d535"
},
{
"name": "name4",
"a_id": "84596",
"b_id": "9ec34be3d535"
},
{
"name": "name5",
"a_id": "d82ebe9815cc",
"b_id": null
}
]
How to get
based on "b_id" "0d687c94c5f4":
id1 = 12345
id2 = 67890
based on "b_id" "9ec34be3d535":
id3 = 23857
id4 = 84596
result = collections.defaultdict(list)
for res in response:
result[res['b_id']].append(res['a_id'])
result:
defaultdict(list,
{'0d687c94c5f4': ['12345', '67890'],
'9ec34be3d535': ['23857', '84596'],
None: ['d82ebe9815cc']})
result = {
item['b_id']: [
subitem['a_id']
for subitem in response
if subitem['b_id'] == item['b_id']
]
for item in response
}
print(result)
>>> {'9ec34be3d535': ['23857', '84596'], '0d687c94c5f4': ['12345', '67890'], None: ['d82ebe9815cc']}
Your request is not very clear.. but I think you mean you want to regroup the list of json with a different key... you can use itertools for that
try this:
import itertools
for key, group in itertools.groupby(r, lambda item: item['b_id']):
print 'b_id', key, [x['a_id'] for x in group]
b_id 0d687c94c5f4 ['12345', '67890']
b_id 9ec34be3d535 ['23857', '84596']
b_id None ['d82ebe9815cc']
or in dictionary form
for key, group in itertools.groupby(r, lambda item: item['b_id']):
print {key: [x['a_id'] for x in group]}
{'0d687c94c5f4': ['12345', '67890']}
{'9ec34be3d535': ['23857', '84596']}
{None: ['d82ebe9815cc']}
i'm looking for an option to calculate the intersection of two JSON-Files. I have been searching for it and found that i can use sets for my problem. This works "okay". But i have to get a more detailed view of the intersection. And this is where the problems are starting.
How i calc the intersection:
def calcIntersect(ValidationFile, json_object1, json_object2):
with open(ValidationFile) as schema_file:
schema = j.load(schema_file)
js.Draft4Validator.check_schema(schema)
with open(json_object1) as spec_file:
spec1 = j.load(spec_file, object_pairs_hook=OrderedDict)
js.validate(spec1, schema)
with open(json_object2) as spec_file:
spec2 = j.load(spec_file, object_pairs_hook=OrderedDict)
js.validate(spec2, schema)
x = set(spec1) & set(spec2)
print(x)
Example Data1:
{
"Car":{
"Brand":"Audi",
"Nationality":"Germany",
"Modelname":"A6"
},
"Engine":{
"cubic capacity":"2967",
"Enginetype":"V6",
"Fuel":"Diesel",
"MaxSpeed":"250"
},
"Colors":{
"Carcolor":"Black",
"Interiorrcolor":"white"
}
}
Example Data2:
{
"Car":{
"Brand":"Audi",
"Nationality":"USA",
"Modelname":"A6"
},
"Engine":{
"cubic capacity":"2995",
"Enginetype":"V6",
"Fuel":"Petrol",
"MaxSpeed":"250"
},
"Colors":{
"Carcolor":"Black",
"Interiorrcolor":"Black"
}
}
Example-Output:
{'Car', 'Colors', 'Engine'}
This are just the "Keys" but i need the dictonaries. At the moment it is giving me this keys to say that there is a intersection in it. Maybe in 'Car' there is in both Files a "Audi" and the nationality is different because one car is produced in America and the other car is produced in Germany. But still it returns 'Car' and not the "Audi".
I hope i were able to describe my problem for a bit. It's my first question..
The following lines, inspired by #likeon's answer, will give you a dictionary whose keys will be the keys of the intersecting objects in your specs, and the values an array containing the intersecting objects.
intersect = { key: [o, spec2[key]] for key, o in spec1.iteritems()
if key in spec2 };
Edit:
If you are using python 3, you must use itemsinstead of iteritems:
intersect = { key: [o, spec2[key]] for key, o in spec1.items()
if key in spec2 };
Why you don't just iterate over spec1 and compare values with spec2 like that:
x = {k: v for k, v in spec1.iteritems() if k in spec2 and spec2[k] == v}
You'll need a recursive solution:
json1 = {
"Car": {
"Brand": "Audi",
"Nationality": "Germany",
"Modelname": "A6"
},
"Engine": {
"cubic capacity": "2967",
"Enginetype": "V6",
"Fuel": "Diesel",
"MaxSpeed": "250"
},
"Colors": {
"Carcolor": "Black",
"Interiorrcolor": "white"
}
}
json2 = {
"Car": {
"Brand": "Audi",
"Nationality": "USA",
"Modelname": "A6"
},
"Engine": {
"cubic capacity": "2995",
"Enginetype": "V6",
"Fuel": "Petrol",
"MaxSpeed": "250"
},
"Colors": {
"Carcolor": "Black",
"Interiorrcolor": "Black"
}
}
def common_dict(d1, d2):
output = {}
for k in set(d1) & set(d2):
o1, o2 = d1[k], d2[k]
if isinstance(o1, dict) and isinstance(o2, dict):
output[k] = common_dict(o1, o2)
elif o1 == o2:
output[k] = o1
return output
print common_dict(json1, json2)
# {'Engine': {'MaxSpeed': '250', 'Enginetype': 'V6'}, 'Car': {'Brand': 'Audi', 'Modelname': 'A6'}, 'Colors': {'Carcolor': 'Black'}}
I'm trying to get the value of each json elements. I am expecting the type to be an array or list but instead, I get type unicode.
Here's my sample json file:
{
"accounts": [
{
"account": {
"basicDetails": {
"accountId": {
"acctName": "Test A",
"acctNumber": "Test B"
},
"accountBranchId": {
"branchName": "Test C",
"brancNumber": "Test D"
},
"cusName": "Test E"
},
"otherDetails": {
"dateCreated": "1999-10-01",
"dateClosed": "2000-10-01"
}
}
}
],
"userExtension": {
"testId": null,
"version": null
},
"status": {
"overallStatus": "S",
"messages": null
},
"_links": null
}
Here is the code I am currently trying
def extract_key(self,obj):
def extract(obj):
if type(obj)== type(OrderedDict()) or isinstance(obj, list):
for k, v in obj.items():
if type(v) == type(OrderedDict()) or type(v)==type(list):
extract(v)
elif type(v) != type(OrderedDict()) or type(v)!=type(list):
print(type(k))
print(k)
results = extract(obj)
return results
def print_keys(self):
with open("C:\\Account.json", "r+") as jsonFile:
data = json.load(jsonFile, object_pairs_hook=OrderedDict)
names = self.extract_key(data)
return names
I'm expecting to get the elements after "accounts": [ but it wont go thru because it treats "accounts" as a unicode instead of a list or array.
You've asked this
if type(obj)== type(OrderedDict()) or isinstance(obj, list):
and entered into the "accounts", that's ok
Then you've just need:
for k, v in obj.items():
if obj.items():
results.append(v)
Results got loaded with:
[OrderedDict([('account', OrderedDict([('basicDetails', OrderedDict([('accountId', OrderedDict([('acctName', 'Test A'), ('acctNumber', 'Test B')])), ('accountBranchId', OrderedDict([('branchName', 'Test C'), ('brancNumber', 'Test D')])), ('cusName', 'Test E')])), ('otherDetails', OrderedDict([('dateCreated', '1999-10-01'), ('dateClosed', '2000-10-01')]))]))])], OrderedDict([('testId', None), ('version', None)]), OrderedDict([('overallStatus', 'S'), ('messages', None)]), None]
Of course results must be declared before that, like:
results = []