How to find length of list in byte format? - python

I have a data variable which contains a list of dicts of lists that i have fetched from an api, formatted as bytes. The list is variable in length.
In: data
Out: b'[{"dict1_list1":[1,2,3],"dict1_list2":[4,5,6]},{"dict2_list1":[1,2,3],"dict2_list2":[4,5,6]}]'
I want to identify when there is only one dict in the list (i.e. the api has run out of data)
In: data
Out: b'[{"onlydict_list1":[1,2,3],"onlydict_list2":[4,5,6]}]'
but because data is formatted as byte I cannot return the length of the list.
In: len(data)
Out: 53 # Not '1' as I would like
How can I identify the length of the list within the b'[....]'?

If r is response then try calling r.json() method . It will convert to a list and then you can find the length of it . You can also use json.loads(r.text) by importing json(import json).

You're getting the length of the bytes object, which is apparently the type of data, not a Python version of the JSON object to which it corresponds.
A simple way to do it would be to first convert the data into the Python object equivalent of the byte-string using json.loads(). Here's what I mean:
import json
data = (b'[{"dict1_list1":[1,2,3],"dict1_list2":[4,5,6]},'
b'{"dict2_list1":[1,2,3],"dict2_list2":[4,5,6]}]')
print(len(json.loads(data))) # -> 2

Related

How to merge two json arrays in Python

I am looping through a WebService in Python which returns me partially data. I am calling the WebService until i receive an "End of Data" in the response.
The returned objects are always the same structure. They are only part of a large data which the WebService returns in chunks of 1000.
I am saving the returned JSON string in a data variable. How can i copy JSON array data_next to JSON array in variable `data' or merge both JSON files.
Let say you receive something like resp1 = '{"data": [...]}' and store it in a dictionary d. Assuming you do that using json package as follows:
d = json.loads(resp1)
For the next batch of data, you should store it in a temporal dictionary td, extract the field "data_next" and append it into the original dictionary:
td = json.loads(respN)
d["data"].append(td["data_next"])
Let us consider two list A =[{"a":"apple"},{"b":"banana"}]
and list B = [{"c":"cat"}]
try below in python 3 to get merged array.
A.__add__(B)

Concatenate json array; issue when adding a unique key

I am scrapping a website full of JSON arrays. I'm trying to concatenate them and add a unique key to every array (see the code below):
For each iteration, the bot calls the function test and if I print get_text, I have this:
{"status":{"code":0,"message":"Ok","user":{"isBanned":false,"isNotConfirmed":false}},"payload":{"vat":0,"price":{"201":{"100":{"batchsize_id":60916,"quantity":100,"product_price":14.12,"shipment_price":8.98,"country_id":"DE"},"200":{"batchsize_id":60922,"quantity":200,"product_price":19.13,"shipment_price":9.06,"country_id":"DE"},"300":{"batchsize_id":60928,"quantity":300,"product_price":23.64,"shipment_price":9.14,"country_id":"DE"},"400":{"batchsize_id":60934,"quantity":400,"product_price":28.4,"shipment_price":9.23,"country_id":"DE"},"500":{"batchsize_id":60940,"quantity":500,"product_price":32.93,"shipment_price":9.32,"country_id":"DE"},"600":{"batchsize_id":60946,"quantity":600,"product_price":37.08,"shipment_price":9.4,"country_id":"DE"},"700":{"batchsize_id":60952,"quantity":700,"product_price":41,"shipment_price":9.48,"country_id":"DE"},"800":{"batchsize_id":60958,"quantity":800,"product_price":44.72,"shipment_price":9.63,"country_id":"DE"},"900":{"batchsize_id":60964,"quantity":900,"product_price":48.24,"shipment_price":9.71,"country_id":"DE"},"1000":{"batchsize_id":60970,"quantity":1000,"product_price":51.59,"shipment_price":9.79,"country_id":"DE"},"minDeliveryDays":5,"maxDeliveryDays":8}},"productionCountry":["DE"],"minDeliveryDays":5,"maxDeliveryDays":8},"pager":{"total":null,"count":null,"current":1}}
And my code below try to concatenate every iteration and add a unique key for each array.
def test(url_final):
get_url = requests.get(url_final)
#get_dict = json.loads(get_url.text)
get_text = get_url.text
print(get_text)
dictionary['a' + str(uuid.uuid4())[:8]] = get_text
print(dictionary)
printit()
My only issue, is that "print dictionary" returns me this:
{'a6a465b1a': '{"status":{"code":0,"message":"Ok","user":{"isBanned":false,"isNotConfirmed":false}},"payload":{"vat":0,"price":{"201":{"100":{"batchsize_id":60916,"quantity":100,"product_price":14.12,"shipment_price":8.98,"country_id":"DE"},"200":{"batchsize_id":60922,"quantity":200,"product_price":19.13,"shipment_price":9.06,"country_id":"DE"},"300":{"batchsize_id":60928,"quantity":300,"product_price":23.64,"shipment_price":9.14,"country_id":"DE"},"400":{"batchsize_id":60934,"quantity":400,"product_price":28.4,"shipment_price":9.23,"country_id":"DE"},"500":{"batchsize_id":60940,"quantity":500,"product_price":32.93,"shipment_price":9.32,"country_id":"DE"},"600":{"batchsize_id":60946,"quantity":600,"product_price":37.08,"shipment_price":9.4,"country_id":"DE"},"700":{"batchsize_id":60952,"quantity":700,"product_price":41,"shipment_price":9.48,"country_id":"DE"},"800":{"batchsize_id":60958,"quantity":800,"product_price":44.72,"shipment_price":9.63,"country_id":"DE"},"900":{"batchsize_id":60964,"quantity":900,"product_price":48.24,"shipment_price":9.71,"country_id":"DE"},"1000":{"batchsize_id":60970,"quantity":1000,"product_price":51.59,"shipment_price":9.79,"country_id":"DE"},"minDeliveryDays":5,"maxDeliveryDays":8}},"productionCountry":["DE"],"minDeliveryDays":5,"maxDeliveryDays":8},"pager":{"total":null,"count":null,"current":1}}'}
How do I remove the string in front of each array?
You are getting the JSON back as a string rather than as a dictionary like you expect. In order to convert from a string into some values, it has to be parsed. You have the right call there, just in the wrong place. Once you have get_text populated (you might want to consider better names), you need to run json_values = json.loads(get_text). Now json_values will contain the dictionary you expect, and you can assign it instead of get_text.

Python/Django Referencing Nested JSON

I'm using the Google Places Reverse Geocode API to return the latitude and longatude of a given address. The API returns a massive JSON file with tons of nested objects. Here's Google's documentation on it.
I'm trying to grab the geometry.location.lat object (see documentation). Here's my current code, followed by the error it returns:
address_coords = gmaps.geocode(raw_address)
# gmaps makes the API request and returns the JSON into address_coords
address_lat = address_coords['results']['geometry']['location']['lat']
address_lon = address_coords['results']['geometry']['location']['lng']
TypeError: List indices must be integers or slices, not str
I'm not sure how to reference that JSON object.
The error is telling you that you're trying to index an array as if it were a property.
Most likely results is the array, so you'd need to do the following to get the value for the first item at index 0:
address_coords['results'][0]['geometry']['location']['lng']
The other possibility is that geometry contains multiple coordinates which you could similarly index:
address_coords['results']['geometry'][0]['location']['lng']
Either way, you should pretty print the structure to see which attributes are arrays versus dictionaries.
import pprint
pprint.pprint(address_coords)

Django query returning too many values

I'm trying to get a list of the names in a table using Django. The field I'm searching for is "name", and I print out my response, which gives the following:
[u"name1", u"name2"]
However, when I send that to a website in javascript, I see that the length is 16, though console.log shows the same result as the python print statements. When I try to iterate over the list that prints as above, I get the integers 0-15 (the loop I am using is
for (var name in names)).
Why is the string representation of this list so much different than the actual representation, and how do I get a representation that matches the print representation if I can't iterate over it or anything?
This is because names is actually a string within your javascript. You need to pass back the json list or convert the stringified json into objects. This second part can be done with JSON.parse(). Unfortunately, your question doesn't show how you're returning the data or how you're handling the data within javascript, so I can't help you any further than this for now.

Accessing Python object in tuple

I am using easyzone and dnspython to extract DNS records from a zone file. When extracting A records I am given back a string and an object in a tuple. I am new to Python coming from PHP and am not quite sure how to get at this object to get the value of it? I had no problems getting the string value in the tuple.
In this code snippet I iterate through the A records and write the values into a CSV:
# Write all A records
for a in z.names.items():
c.writerow([domain, 'A', a.__getitem__(0), a])
a contains the following:
('www.121dentalcare.com.', <easyzone.easyzone.Name object at 0x1012dd190>)
How would I access this object within a which is in the 2nd half of this tuple??
You can use indices to get items from a tuple:
sometuple[1]
just as you can do with lists and strings (see sequence types).
The documentation of easyzone is a little on the thin side, but from looking at the source code it appears the easyzone.easyzone.Name objects have .name, .soa and .ttl attributes:
print sometuple[1].name
The .soa attribute is another custom class, with .mname, .rname, .serial, .refresh, .retry, .expire and .minttl properties.

Categories