I apologize if this is a very basic question, but I built multiple dictionaries using nested loops and I cannot return all the dictionaries, it only returns the first one. I know a part of this is because return is in the wrong indentation, but Python will only allow return data to be indented there. Is there any way to change this function so it returns all the dictionaries?
import urllib.request
import json
def get_url(url):
text = urllib.request.urlopen(url).read().decode()
return text
def display_json(text):
dictionary = json.loads(text)
for item in dictionary['items']:
for article in item['articles']:
line = (article['article'], article['views'])
data = dict([line])
return data
def function(data):
print(data)
def main():
url = "https://wikimedia.org/api/rest_v1/metrics/pageviews/top/en.wikiversity/all-access/2018/01/all-days"
text = get_url(url)
data = display_json(text)
function(data)
main()
Use dictionary comprehension
def display_json(text):
return {
item['article']:item['views'] for item in
json.loads(text)['items'][0]['articles']
}
The JSON is structured as follows:
There is no need to loop through items, b'coz it has only one element. We can just get the first element using json.loads(text)['items'][0]. Even if there is more than one item inside items, you can still manage it inside the comprehension.
use a generator
def display_json(text):
dictionary = json.loads(text)
for item in dictionary['items']:
for article in item['articles']:
line = (article['article'], article['views'])
data = dict([line])
yield data
data = list(display_json(text))
Related
I can't seems to wrap my head around this silly issue. There are API requests that run simultaneously 23 different section stored in a dictionary :
polygonsDict = {
'Sect1':'100,6.3',
'Sect2':'100,6.0',
'Sect3':'100,5.5' # and more sections
}
urlDict = {
'traffic': 'https://google.com'
}
Here is the code where I iteratively :
section_key = list(polygonsDict.keys()) #convert the dictionary key to list for iteration
for idx, section in enumerate(section_key):
traffics(section ,urlDict['traffic']+polygonsDict[section]).getPolygonTraffics() #This line is constructing the link for request.
Then, the link is send to a class called traffics with getPolygonTraffics function :
class traffics:
def __init__(self, name, traffics):
self.traffics = traffics
self.name = name
def getPolygonTraffics(self):
try :
print("TRF: Running for "+self.name+"...")
raw = req.get(self.traffics).json()
traffics_raw = [raw] #wrap the dict to list
traffics_ls = []
for ls in traffics_raw:
traffics_ls.append(ls)
#Melt the list of dictionary to form a DataFrame
traffics_df = pd.DataFrame(traffics_ls).explode('jams').reset_index(drop=True)
print(traffics_df)
#exception when `jams` is not found in the list of dict.
except KeyError:
print("Skip!")
In getPolygonTraffics, I want to append every traffics_raw (the json requests) to one individual list and eventually, explode them to a dataFrame. How can I achieve this? I'm not very sure how to explain this.
Current output is multiple lists of each dictionary :
[{}]
[{}]
WHat I want is : [{},{},{}]. Then explode to DataFrame.
I'm querying a REST API url & I'm trying to return all the dictionary sets, but only able to return one key pair.
Dictionary Output in the print statement inside for loop is the expected output, when when returned only one set of key pair is appearing.
Expected Dictionary looks like:
{'IncidentID': 'IM10265'}
{'IncidentID': 'IM10266'}
{'IncidentID': 'IM10267'}
{'IncidentID': 'IM10268'}
Code:
import json , requests
sm1 = requests.get('http://Rest Url', auth=('XX','YY'))
z = json.loads(sm1.text)
def get_im_list():
incidentlist_access = z['content']
for im_data in incidentlist_access:
Access_imslist = im_data['Incident']
print(Access_imslist)
#print(type(Access_imslist))
#return Access_imslist
data = get_im_list()
#print(data)
So when when I'm un-commentating
return Access_imslist & print(data)
I'm only receiving the output as:
{'IncidentID': 'IM10265'}
not the complete dictionary.
Every time you loop through the data, Access_imslist gets overwritten, so when you (presumably) return Access_Imlist it's only returning the last value.
You need to create a data structure outside of the for loop, add each bit of data to it, then return that instead. Something like:
def get_im_list():
incident_data = []
incidentlist_access = z['content']
for im_data in incidentlist_access:
incident_data.append(im_data['Incident'])
return incident_data
hope that helps!
you need to define a variable list , and then append the Access_imslist values to that variable.
like this :
data = []
def get_im_list():
incidentlist_access = z['content']
for im_data in incidentlist_access:
Access_imslist = im_data['Incident']
data.append(Access_imslist)
print(data)
i have a document containing a dict of results, what i want to do is loop through the document and save each result that is right
this is my current code which works fine but will only the return the first result
#Fetch router descriptors based on a given flag
def getHSDirFlag():
for r in router.itervalues():
if 'HSDir' in r['flags']:
return r
return None
i have tried :
def getHSDirFlag():
HSDirList =()
for r in router.itervalues():
if 'HSDir' in r['flags']:
HSDirList += r
return HSDirList
return None
but get the error TypeError: can only concatenate tuple (not "dict") to tuple
what is the best data type to save a dict to and how can i loop through the doc finding every result
First, why would you call a variable HSDirList and make it a tuple, not a list?!
Second, why return the "list" inside the for loop, then tack a return None (which will never be reached) to the end of the function?
Try:
def getHSDirFlag(router):
HSDirList = [] # an actual list
for r in router.itervalues():
if 'HSDir' in r['flags']:
HSDirList.append(r) # add to the list
return HSDirList # return the list
Note that the return is outside the for loop, so doesn't happen until you've iterated over all itervalues. Also, router is now an argument to the function, rather than relying on scope.
Finally, you should read and consider implementing the Python style guide, PEP-0008.
you can save your dictionaries in JSON file ! in this code you have a tuple and you want to concatenate dictionaries on it but i suggest you use JSON for saving dicts !
this code is for saving a json file :
import json
with open('data.json', 'wb') as fp:
json.dump(data, fp)
and this one for load
with open('data.json', 'rb') as fp:
data = json.load(fp)
read more at https://docs.python.org/2/library/json.html
I want a function to return me the value of the equation for every number in the list. I have a list of 24 parameters, and I need to solve an equation for every value of this list.
This is the way I get my list:
wlist=[]
def w(i):
for i in range(24):
Calctruesolar=((i*60/1440)*1440+eq_time()+4*long-60*timezone)%1440
if Calctruesolar/4<0:
Calcw=(Calctruesolar/4)+180
wlist.append(Calcw)
print(Calcw)
else:
Calcw=(Calctruesolar/4)-180
wlist.append(Calcw)
print(Calcw)
Then, the list is this one:
>>> wlist=
[166.24797550450222, -178.75202449549778, -163.75202449549778, -148.75202449549778, -133.75202449549778, -118.75202449549778, -103.75202449549778, -88.75202449549778, -73.75202449549778, -58.75202449549778, -43.75202449549778, -28.75202449549778, -13.752024495497778, 1.2479755045022216, 16.24797550450222, 31.24797550450222, 46.24797550450222, 61.24797550450222, 76.24797550450222, 91.24797550450222, 106.24797550450222, 121.24797550450222, 136.24797550450222, 151.24797550450222]
Now, I use the next function:
def hourly_radiation(wlist):
for i in wlist:
Calcrt=(math.pi/24)*(a()+b()*math.cos(math.radians(i)))*((math.cos(math.radians(i)))-math.cos(math.radians(wss())))/(math.sin(math.radians(wss()))-((math.pi*wss()/180)*math.cos(math.radians(wss()))))
CalcI=Calcrt*radiation
print(Calcrt,CalcI)
So, I want to receive Calcrt and CalcI for every value inside the list. But it doesn't work. I have been looking for information in internet and tutorials but I didn't find anything.
Try this:
def hourly_radiation(wlist):
rt_list = []
I_list = []
for i in wlist:
Calcrt = (math.pi/24)*(a()+b()*math.cos(math.radians(i)))*((math.cos(math.radians(i)))-math.cos(math.radians(wss())))/(math.sin(math.radians(wss()))-((math.pi*wss()/180)*math.cos(math.radians(wss()))))
CalcI = Calcrt*radiation
rt_list.append(Calcrt)
i_list.append(CalcI)
print(Calcrt,CalcI)
dict = {}
dict["Calcrt"] = rt_list
dict["CalcI"] = i_list
return dict
This would return the values as a dictionary containing two lists. You may use any data structure that matches your requirements.
You may also create a tuple in each loop run and append it to a list and return it, like:
def hourly_radiation(wlist):
rt_list = []
data = ()
for i in wlist:
Calcrt = (math.pi/24)*(a()+b()*math.cos(math.radians(i)))*((math.cos(math.radians(i)))-math.cos(math.radians(wss())))/(math.sin(math.radians(wss()))-((math.pi*wss()/180)*math.cos(math.radians(wss()))))
CalcI = Calcrt*radiation
data = (Calcrt, CalcI)
print(Calcrt, CalcI)
rt_list.append(data)
return rt_list
I have not run or tested this code, but I hope it should work.
Please use this as a starting point and not as a copy-paste solution.
im creating a function that will handle xml data, the data can vary but the structure is the same :
events ( list like )
event
info
additional info
the function needs to create a dictionary that contains a mapping in which if the data being looped is not 0 then the data needs to be mapped in a dictionary, heres my solution:
def parse_items(self, xml):
""" Builds a dynamic dictionary tree wich holds each event in a dictionary
that can be accessed by number of event """
parsed_items = {}
parsed_item = {}
sub_info = {}
for num, item in enumerate(xml):
for tag in item:
if len(tag) != 0:
for info in tag:
sub_info[info.tag] = info.text
parsed_item[tag.tag] = sub_info
# Need to flush the dictionary else it will repeat info
sub_info = {}
else:
parsed_item[tag.tag] = tag.text
parsed_items[num] = parsed_item
# Need to flush the dictionary else it will repeat info
parsed_item = {}
return parsed_items
my question is, is there a way to make this dynamically without having to make for loops for every level of data ?
(Reposting as an answer, because the questioner intends to use the idea)
In the latest versions of Python, there are dict comprehensions as well as list comprehensions. Like this:
sub_info = {i.tag: i.text for i in tag}