Hi I need help to create a new list from looping through JSON output file "ruletree"
ruletree = {
"account": "act_F-AC-1234",
"contract": "ctr_F-1234",
"propertyName": "www.domain.com",
"rules": {
"name": "default",
"children": [
{
"name": "Route One",
"children": [],
"behaviors": [
{
"name": "origin",
"options": {
"originType": "CUSTOMER",
"hostname": "first.gateway.com",
},
}
],
},
{
"name": "Route Two",
"children": [],
"behaviors": [
{
"name": "origin",
"options": {
"originType": "CUSTOMER",
"hostname": "second.gateway.com",
},
}
],
},
],
},
}
my code looks like this, getting error "TypeError: list indices must be integers or slices, not str"
hostnames = []
for host in ruletree['rules']['children']['behaviors']['options']:
options.get('hostname', N/A)
hostnames.append(host)
print(hostnames)
expected output
{"propertyName": "www.domain.com", "hostnames": "first.gateway.com, second.gateway.com"}
3
Answers
You missed that
children
andbehaviors
are lists, not dictionaries, so you can’t use string indices to fetch their values.Fixed your code as follows:
Output:
so this error means that in a list, you are trying to index using a string.
Here’s an example
As per your output json file, that error is coming because ruletree[rules][children] is a list.
So, you need to iterate this as well.
Another issue I see is you are using options.get but the iterating variable is host, so even if you iterate right, your iterating variable was wrong, so that needs to be corrected as well.
Here’s the correct code
@Zero has already identified and solved your problem.
However, if you’re spending much time parsing and querying json, it could be useful to be aware of the jmespath package.
With jmespath you could extract your hostnames as:
Additionally, one could go further and create your full desired output:
with:
Edit: desired output of OP has changed.
If you created a list of hostnames, you can make it into a comma separated string with
", ".join(hostnames)
.Alternatively, if you are opting for a jmespath approach:
or for the full output in a single go: