Organizing of Dynamic Lists of Lists - python

I'm sorry if this has been answered (I looked and did not find anything.) Please let me know and I will delete immediately.
I am writing a program that makes an API call which returns a multiple lists of different length depending on the call (e.g. facebook API call. Enter the persons name and a list of pictures is returned and each picture has a list of of who "liked" each photo. I want to store a list of a list of these "likes").
#Import urllib for API request
import urllib.request
import urllib.parse
#First I have a function that takes two arguments, first and last name
#Function will return a list of all photos the person has been tagged in facebook
def id_list_generator(first,last):
#Please note I don't actually know facebook API, this part wil not be reproducible
pic_id_request = urllib.request.open('www.facebook.com/pics/id/term={first}+{last}[person]')
pic_id_list = pic_id_request.read()
for i in pic_id_list:
id_list.append(i)
return(id_list)
#Now, for each ID of a picture, I will generate a list of people who "liked" that picture.
#This is where I have trouble. I don't know how to store these list of lists.
for i in id_list:
pic_list = urllib.request.open('www.facebook.com/pics/id/like/term={i}[likes]')
print pic_list
This would print multiple lists of "likes" for each picture the person was tagged in:
foo, bar
bar, baz
baz, foo, qux
norf
I don't really know how to store these honestly.
I was thinking of using a list that would look like this after appending:
foo = [["foo", "bar"], ["bar","baz"],["baz","foo","qux"],["norf"]]
But really I'm not sure what type of storage to use in this case. I thought of using a dictionary of a dictionary, but I don't know if the key can be iterable. I feel like there is a simple answer to this that I am missing.

Well, you could have a list of dictionaries:
Here's an example:
facebook_likes = [{
"first_name": "John",
"last_name": "Smith",
"image_link": "link",
"likes": ["foo"]
}, {
"first_name": "John",
"last_name": "Doe",
"image_link": "link",
"likes": ["foo", "bar"]
}]
for like in facebook_likes:
print like
print like["likes"]
print like["likes"][0]
You should also look into JSON objects.
Its one of the standard response objects that you get after making API calls.
Fortunately, its very simple to transform a Python dict into a JSON object and vice versa.

If you just want to sort by the first element in each list, Python does that by default for 2D lists. Refer to this thread: Python sort() first element of list

Related

Work with nested objects using couchdb-python

Disclaimer: Both Python and CouchDB are new for me. So far my "programming" has mostly consisted of Bash scripts.
I'm trying to create a small script that updates objects in a CouchDB database. The objects however aren't created by my script but by an App called Tap Forms that uses CouchDB for sync. Basically I'm trying to automatically update the content of the app. That also means I can't really influence the structure or names of the objects in CouchDB.
The Database is mostly filled with objects of this structure:
{
"_id": "rec-3b17...",
"_rev": "21-cdf6...",
"values": {
"fld-c3d4...": 4,
"fld-1def...": 1000000000000,
"fld-bb44...": 760000000000,
"fld-a44f...": "admin,name",
"fld-5fc0...": "SSD",
"fld-642c...": true,
},
"deviceName": "MacBook Air",
"dateModified": "2019-02-08T14:47:06.051Z",
"dateCreated": "2019-02-08T11:33:00.018Z",
"type": "frm-7ff3...",
"dbID": "db-1435...",
"form": "frm-7ff3..."
}
I shortened the numbers a bit and removed some entries to increase readability.
Now the actual values I'm trying to update are within the "values" : {...} array (or object, or list, guess I don't have much experience with JSON either).
As I know some of these values, I managed to create view that finds the _id of an object on the server. I then use the python-couchdb module as described in documentation:
for item in db.view('CustomViews/test2', key="GENERIC"):
doc = db[item.id]
This gives me the object. However I want to update one of the values within the values array, lets say fld-c3d4.... But how? Using doc['values'] = 'new_value' updates the whole array. I tried other (seemingly logical) ways along the lines of doc['values['fld-c3d4']'] = 'new_value' but couldn't wrap my head around it. I couldn't find an example in any documentation.
So here's a example how to update the fld-c3d4.
You have your document that represent a dictionary with nested dictionary.
If you want to get the values, you will do something like this:
values = doc['values']
Now the variable values points to the values in your document.
From there, you can access a sub value:
values['fld-c3d4'] = 'new value'
If you want to directly update the value from the doc, you just have to chain those operations:
doc['values']['fld-c3d4'] = 'new value'

get a value from a json file that contains multiple json objects

i am new to python and json I'm trying to get a specific value for each of the objects that are stored. i am trying to print all of the attributes stores under "NAME" and "OBJECTID" . how can i do this? i have been looking at different answers but I'm still confused. (EDIT: most of the objects in the whole file have different names, my objective is to create a list of all of the names.)
here is a small sample of the file i am using.
thank you for your help!
{"type":"FeatureCollection", "features": [
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[552346.2856999999,380222.8998000007]]]]},"properties":{"OBJECTID":1,"STFID":"55001442500001","NAME":"0001"}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[529754.7249999996,409135.9135999996],[529740.0305000003,408420.03810000047]]]},"properties":{"OBJECTID":2,"STFID":"55001537250001","NAME":"0001","COUSUBFP":"53725"}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[508795.9363000002,441655.3672000002],[508813.49899999984,441181.034]]]},"properties":{"OBJECTID":6278,"STFID":"55141885750001","NAME":"0001","COUSUBFP":"88575"}}
]}
Assuming your json is like
json = {"type": "FeatureCollection",
"features": [
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[552346.2856999999,380222.8998000007]]]},"properties":{"OBJECTID":1,"STFID":"55001442500001","NAME":"0001"}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[529754.7249999996,409135.9135999996],[529740.0305000003,408420.03810000047]]]},"properties":{"OBJECTID":2,"STFID":"55001537250001","NAME":"0001","COUSUBFP":"53725"}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[508795.9363000002,441655.3672000002],[508813.49899999984,441181.034]]]},"properties":"OBJECTID":6278,"STFID":"55141885750001","NAME":"0001","COUSUBFP":"88575"}}
]}
You can get a list of tuples with OBJECTID, NAME using a list comprehension like this:
oid_name = [(feature['properties']['OBJECTID'], feature['properties']['NAME']) for feature in json['features']]
which will evaluate to
[(1, '0001'), (2, '0001'), (6278, '0001')]
in this example.
If your need is to look up the name for an object, you might find it more useful to use a dictionary for this:
names = {feature['properties']['OBJECTID']: feature['properties']['NAME'] for feature in json['features']}
This will allow you to look up the name like this:
>>> names[1]
'0001'

How do I pull a recurring key from a JSON?

I'm new to python (and coding in general), I've gotten this far but I'm having trouble. I'm querying against a web service that returns a json file with information on every employee. I would like to pull just a couple of attributes for each employee, but I'm having some trouble.
I have this script so far:
import json
import urllib2
req = urllib2.Request('http://server.company.com/api')
response = urllib2.urlopen(req)
the_page = response.read()
j = json.loads(the_page)
print j[1]['name']
The JSON that it returns looks like this...
{
"name": bill jones,
"address": "123 something st",
"city": "somewhere",
"state": "somestate",
"zip": "12345",
"phone_number": "800-555-1234",
},
{
"name": jane doe,
"address": "456 another ave",
"city": "metropolis",
"state": "ny",
"zip": "10001",
"phone_number": "555-555-5554",
},
You can see that with the script I can return the name of employee in index 1. But I would like to have something more along the lines of: print j[**0 through len(j)**]['name'] so it will print out the name (and preferably the phone number too) of every employee in the json list.
I'm fairly sure I'm approaching something wrong, but I need some feedback and direction.
Your JSON is the list of dict objects. By doing j[1], you are accessing the item in the list at index 1. In order to get all the records, you need to iterate all the elements of the list as:
for item in j:
print item['name']
where j is result of j = json.loads(the_page) as is mentioned in your answer
Slightly nicer for mass-conversions than repeated dict lookup is using operator.itemgetter:
from future_builtins import map # Only on Py2, to get lazy, generator based map
from operator import itemgetter
for name, phone_number in map(itemgetter('name', 'phone_number'), j):
print name, phone_number
If you needed to look up individual things as needed (so you didn't always need name or phone_number), then regular dict lookups would make sense, this just optimizes the case where you're always retrieving the same set of items by pushing work to builtin functions (which, on the CPython reference interpreter, are implemented in C, so they run a bit faster than hand-rolled code). Using a generator based map isn't strictly necessary, but it avoids making (potentially large) temporary lists when you're just going to iterate the result anyway.
It's basically just a faster version of:
for emp in j:
name, phone_number = emp['name'], emp['phone_number']
print name, phone_number

How to iterate through this nested json array with python

So I made an API call to JIRA to get the list of all the issues. It returns something like this:
{
issues: [
{
fields: {
description:
summary:
creator:
reporter:
priority:
}
}
]
and I'm trying to get to what's inside fields.
Here's what I have:
response = requests.get(url + '/search?jql=resolution%20=%20Unresolved%20order%20by%20priority%20DESC,updated%20DESC', auth=auth).json()
and then :
response['issues'] works. But I can't find a way to access fields and then the elements inside it. I thought about iterating through but not sure if there's a simpler solution.
My understanding is that response[issues] is a list and I know how to access each element of it response[issues][0] but how to access the object nested inside the list? (still researching on it -- might find an answer)
if you look at your json it's an array to a hash or list to dict. To get fields you'd just call the first array element and the key.
response[issues][0][fields]

Parsing Json data sent by android clinet using "post" request in django view

I am trying to loop around a json data sent by my android client. I used the code below but its not working for me. Any possible error that I am doing...????
def api_json(request):
try:
x101=json.loads(request.body)
print x101
for data in x101:
print data+"xp"
asset_code=data['asset_code']
credential=data['credential']
d1=data['d1']
d2=data['d2']
d3=data['d3']
angle=data['angle']
status=data['status']
operator=data['operator']
location=data['location']
print asset_code,credential,d1,d2,d3,angle,status,operator,location
v=Verification(asset_code=asset_code,
scan_time=datetime.datetime.now(),
credential=credential,
d1=d1,
d2=d2,
d3=d3,
angle=angle,
status=status,
operator=operator,
location=location,
image='')
v.save()
except:
print 'nope'
return HttpResponse('success')
error trace:
TypeError: string indices must be integers
Assuming your JSON decodes to a dictionary, for data in x101 iterates through the keys of that dictionary. So data['d1'] will give the TypeError that you see, "string indices must be integers".
Since you have given absolutely no details about what the data structure actually looks like, we can only guess, but you perhaps want to iterate through the dict's values with for data in x101.values().
In any case, you should definitely remove that try/except that does nothing except print "nope". Errors are there for a reason, and silencing them will only prevent you from debugging properly, as we see here.
Edit
x101 is just a single dict. You say that there will frequently be more than one dict, but it can't possibly work like that: the only way to have multiple dicts is to have them inside a list (ie a JSON array). And if so, they would have to always be in a list, even when there is just one. So your structure should be:
[
{
"angle": "10",
"asset_code": "XPS1020",
"credential": "wqw2323ds2",
"d1": "1",
"d2": "2",
"d3": "3",
"location": "Bangalore",
"operator": "pradeep",
"status": "1"
}
]
and then your code will work as is, whether there is a single dict or many.

Categories

Resources