I have the following json data
data_fixt_json =
{"api": {"results": 402,
"fixtures": [{
"fixture_id": 127807,
"league_id": 297,
"homeTeam": {
"team_id": 2279,
"team_name": "Tigres UANL",
"logo":"url"},
"awayTeam": {
"team_id": 2282,
"team_name": "Monterrey",
"logo": "url"},
"goalsHomeTeam": 1,
"goalsAwayTeam": 0,
"score": {
"halftime": "1-0",
"fulltime": "1-0",
"extratime": null,
"penalty": null}}
I need to store in each key:value pairs in variables than use this variables to create objects in my database. I tried the following code
data_json =
date_fixt_json["api"["fixtures"]
for item in data_json:
fixture_id = item["fixture_id"]
league_id = item["league_id"]
But when for loop go up to the dict "homeTeam" my script arrise error. How i can write code which will iterate through my json data and provide me opportunities to store values in variables
If you'd like to iterate over the entries in a dict, you can do:
for fixture in date_fixt_json['api']['fixtures']:
for key, value in fixture.items():
print('key: {}, value: {}'.format(key, value))
There are a few things to think about here.
Do you know the number of items in the array?
If you do, then consider simply using indexing to access the values - in this use case they are similar to variables.
data_array = ["api"]["fixtures"]
fixture_id1 = data_array[0]["fixture_id"]
Do you require variables?
If you absolutely have to use variables, you can use the following concept, however I strongly recommend against doing this:
example = ['k', 'l', 'm', 'n']
for n, val in enumerate(example):
globals()[f"var{n}"] = val
print(var2)
>>> m #Output
Let me know if this helps - happy coding!
Related
Alright, so I'm struggling a little bit with trying to parse my JSON object.
My aim is to grab the certain JSON key and return it's value.
JSON File
{
"files": {
"resources": [
{
"name": "filename",
"hash": "0x001"
},
{
"name": "filename2",
"hash": "0x002"
}
]
}
}
I've developed a function which allows me to parse the JSON code above
Function
def parsePatcher():
url = '{0}/{1}'.format(downloadServer, patcherName)
patch = urllib2.urlopen(url)
data = json.loads(patch.read())
patch.close()
return data
Okay so now I would like to do a foreach statement which prints out each name and hash inside the "resources": [] object.
Foreach statement
for name, hash in patcher["files"]["resources"]:
print name
print hash
But it only prints out "name" and "hash" not "filename" and "0x001"
Am I doing something incorrect here?
By using name, hash as the for loop target, you are unpacking the dictionary:
>>> d = {"name": "filename", "hash": "0x001"}
>>> name, hash = d
>>> name
'name'
>>> hash
'hash'
This happens because iteration over a dictionary only produces the keys:
>>> list(d)
['name', 'hash']
and unpacking uses iteration to produce the values to be assigned to the target names.
That that worked at all is subject to random events even, on Python 3.3 and newer with hash randomisation enabled by default, the order of those two keys could equally be reversed.
Just use one name to assign the dictionary to, and use subscription on that dictionary:
for resource in patcher["files"]["resources"]:
print resource['name']
print resource['hash']
So what you intend to do is :
for dic in x["files"]["resources"]:
print dic['name'],dic['hash']
You need to iterate on those dictionaries in that array resources.
The problem seems to be you have a list of dictionaries, first get each element of the list, and then ask the element (which is the dictionary) for the values for keys name and hash
EDIT: this is tested and works
mydict = {"files": { "resources": [{ "name": "filename", "hash": "0x001"},{ "name": "filename2", "hash": "0x002"}]} }
for element in mydict["files"]["resources"]:
for d in element:
print d, element[d]
If in case you have multiple files and multiple resources inside it. This generalized solution works.
for keys in patcher:
for indices in patcher[keys].keys():
print(patcher[keys][indices])
Checked output from myside
for keys in patcher:
... for indices in patcher[keys].keys():
... print(patcher[keys][indices])
...
[{'hash': '0x001', 'name': 'filename'}, {'hash': '0x002', 'name': 'filename2'}]
I have JSON output as follows:
{
"service": [{
"name": ["Production"],
"id": ["256212"]
}, {
"name": ["Non-Production"],
"id": ["256213"]
}]
}
I wish to find all ID's where the pair contains "Non-Production" as a name.
I was thinking along the lines of running a loop to check, something like this:
data = json.load(urllib2.urlopen(URL))
for key, value in data.iteritems():
if "Non-Production" in key[value]: print key[value]
However, I can't seem to get the name and ID from the "service" tree, it returns:
if "Non-Production" in key[value]: print key[value]
TypeError: string indices must be integers
Assumptions:
The JSON is in a fixed format, this can't be changed
I do not have root access, and unable to install any additional packages
Essentially the goal is to obtain a list of ID's of non production "services" in the most optimal way.
Here you go:
data = {
"service": [
{"name": ["Production"],
"id": ["256212"]
},
{"name": ["Non-Production"],
"id": ["256213"]}
]
}
for item in data["service"]:
if "Non-Production" in item["name"]:
print(item["id"])
Whatever I see JSON I think about functionnal programming ! Anyone else ?!
I think it is a better idea if you use function like concat or flat, filter and reduce, etc.
Egg one liner:
[s.get('id', [0])[0] for s in filter(lambda srv : "Non-Production" not in srv.get('name', []), data.get('service', {}))]
EDIT:
I updated the code, even if data = {}, the result will be [] an empty id list.
my data is
my_dict = {
u'samosa': {
u'shape': u'triangle',
u'taste': None,
u'random': None,
u'salt': u'7.5.1'
},
u'idli': {
u'color': u'red',
u'eattime': u'134'
},
u'ridgegaurd': {},
u'sambhar': {
u'createdate': u'2016-05-12',
u'end time': u'10655437'
}
}
There are four keys samosa, idli, ridgegaurd and sambhar.
I don't want whole part of the values. I just want to get
value(shape) from samosa,
values(color and eattime) from idli
values(createdate and endtime) from sambhar
I want only the above values. I tried using dict but was not able to. Is it possible to write regular expressions for this?
If the value of a dictionary entry is another dictionary, you can simply index it again.
my_dict[u'samosa'][u'shape']
my_dict[u'idli'][u'color'], my_dict[u'idli'][u'eattime']
my_dict[u'sambhar'][u'createdate'], my_dict[u'sambhar'][u'endtime']
This function will recursively run through json and return a single dictionary with all the information, thus making it much easier to access your data:
def flatten(data):
flattened = {}
for k, v in data.items():
if isinstance(v, dict):
flattened.update(flatten(v))
else:
flattened[k] = v
return flattened
I have two JSON files that look like this
{"type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { **"id"**: "Carlow", **"density"**: "0" } , "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -6.58901, 52.906464 ], [ -6.570265, 52.905682 ], [ -6.556207, 52.906464 ],
Second JSON file
{"features": [{"**count**": 2, "name": "**Sligo**"}, {"count": 3"name":"Fermanagh"},{"count": 1, "name": "Laois"},
I am trying to check if "id" in the first file matches with "name" in the second file and if so change the value for "density" to the value for "count" from the second file. I am looking at using recursion from a similar question I found here Replace value in JSON file for key which can be nested by n levels but it only checks if one key matches and changes value. I need two keys to match before changing values. This is the code I have used so far but not sure how to add two keys and two values. I use Counter to count the number of times a string appears and save it to county_names.json, which is my second JSON file. ire_countiesTmp.json is my first file that I am trying to replace the values with from the second file. Im not sure how to do this with Python as only started learning it. Any help would be great, or if you know a better way. Thanks
import json, pprint
from collections import Counter
with open('../county_names.json') as data_file:
county_list = json.load(data_file)
for i in county_list:
c = Counter(i for i in county_list)
for county,count in c.iteritems():
with open('ire_countiesTmp.json') as f:
def fixup(adict, k1, v1, k2, v2):
for key in adict.keys():
if adict[key] == v1:
adict[key] = v
elif type(adict[key]) is dict:
fixup(adict[key], k, v)
#pprint.pprint( data )
fixup(data, 'id', county, 'density', count)
pprint.pprint( data )
Generally speaking, recursion is not a good idea in Python. The compiler/interpreter does not handle it well and it becomes terribly slow, as there is no tail recursion optimisation: Why is recursion in python so slow? .
A possible brute-force-solution that assumes you have converted your JSON-data into a dict could look like this:
def fixup_dict_a_with_b(a, b):
for feature_a in a["features"]:
for feature_b in b["features"]:
if feature_a["properties"]["id"] == feature_b["name"]:
feature_a["properties"]["density"] = feature_b["count"]
break
This can of course be "abstractified" to your liking. ;)
Other, more elegant solutions exist, but this one is straightforward and easy to get when you just started to use Python. (Eventually, you might want to look into pandas, for example.)
I have a json file that contains about 100,000 lines in the following format:
{
"00-0000045": {
"birthdate": "5/18/1975",
"college": "Michigan State",
"first_name": "Flozell",
"full_name": "Flozell Adams",
"gsis_id": "00-0000045",
"gsis_name": "F.Adams",
"height": 79,
"last_name": "Adams",
"profile_id": 2499355,
"profile_url": "http://www.nfl.com/player/flozelladams/2499355/profile",
"weight": 338,
"years_pro": 13
},
"00-0000108": {
"birthdate": "12/9/1974",
"college": "Louisville",
"first_name": "David",
"full_name": "David Akers",
"gsis_id": "00-0000108",
"gsis_name": "D.Akers",
"height": 70,
"last_name": "Akers",
"number": 2,
"profile_id": 2499370,
"profile_url": "http://www.nfl.com/player/davidakers/2499370/profile",
"weight": 200,
"years_pro": 16
}
}
I am trying to delete all the items that do not have a gsis_name property. So far I have this python code, but it does not delete any values (note: I do not want to overwrite the original file)
import json
with open("players.json") as json_file:
json_data = json.load(json_file)
for x in json_data:
if 'gsis_name' not in x:
del x
print json_data
You're deleting x, but x is a copy of the original element in json_data; deleting x won't actually delete it from the object that it was drawn from.
In Python, if you want to filter some items out of a collection your best bet is to copy the items you do want into a new collection.
clean_data = {k: v for k, v in json_data.items() if 'gsis_name' in v}
and then write clean_data to a file with json.dump.
When you say del x, you are unassigning the name x from your current scope (in this case, global scope, since the delete is not in a class or function).
You need to delete it from the object json_data. json.load returns a dict because your main object is an associative array / map / Javascript object. When you iterate a dict, you are iterating over the keys, so x is a key (e.g. "00-0000108"). This is a bug: You want to check whether the value has the key gsis_name.
The documentation for dict shows you how to delete from a dict using the key: https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
del d[key]
Remove d[key] from d. Raises a KeyError if key is not in the map.
But as the other answers say, it's better to create a new dict with the objects you want, rather than removing the objects you don't want.
Just create new dict without unwanted elements:
res = dict((k, v) for k, v in json_data.iteritems() if 'gsis_name' in json_data[k])
Since Python 2.7 you could use a dict comprehension.