Strange Results when trying to create JSON output from simple Python Array - python

I have written this code:
myarray = []
myarray.append('abc')
myarray.append('def')
return json.dumps(myarray)
This is part of a GraphQL function. What I get back is the equivalent of this:
"myArray": "[\"abc\", \"def\"]"
How can I eliminate the backslashes?
Robert

You haven't shown enough code to reproduce this error. Presumably, whatever is calling this function is also converting to json. So you should return myarray directly, without converting to json in this function.

My predicament turned out to be that GraphQL (via Graphene-Django) was already turning the array into JSON. Thus I was effectively converting to JSON twice. I solved the problem by just returning myarray directly.

Related

Is there something like a reverse eval() function?

Imagine the following problem: you have a dictionary of some content in python and want to generate python code that would create this dict. (which is like eval but in reverse)
Is there something that can do this?
Scenario:
I am working with a remote python interpreter. I can give source files to it but no input. So I am now looking for a way to encode my input data into a python source file.
Example:
d = {'a': [1,4,7]}
str_d = reverse_eval(d)
# "{'a': [1, 4, 7]}"
eval(str_d) == d
repr(thing)
will output text that when executed will (in most cases) reproduce the dictionary.
Actually, it's important for which types of data do you want this reverse function to exist. If you're talking about built-in/standard classes, usually their .__repr__() method returns the code you want to access. But if your goal is to save something in a human-readable format, but to use an eval-like function to use this data in python, there is a json library.
It's better to use json for this reason because using eval is not safe.
Json's problem is that it can't save any type of data, it can save only standard objects, but if we're talking about not built-in types of data, you never know, what is at their .__repr__(), so there's no way to use repr-eval with this kind of data
So, there is no reverse function for all types of data, you can use repr-eval for built-in, but for built-in data the json library is better at least because it's safe

Decoding an API list and breaking it up in Python 3?

I'm hoping to get your help on decoding a response I'm getting from an API into Python 3, and break it down into variables. It's almost a list, see for yourself:
API returns this:
['b', "[[1465617600000,591.41,651.95,587.96,647.45,1474960.0,240144.89982940466],[1465704000000,647.2,700.68,644.09,698.55,1605710.0,242030.50812923996]]'"]
I'll assign that to lets say.. variable apiReturn. I'm trying to break all the numbers down into individual variables, specifically with the formatting.
I'd like to do something like:
print(apiReturn[0][0])
and get:
1465185600000
Just playing around with trying to print that data here, to no avail:
print(apiReturn.split("'"))
print(apiReturn.split("'"[0][0]))
print(apiReturn.split("[", 1 )[1][0])
Use ast.literal_eval:
import ast
api_return = apiReturn[1][:-1] # [:-1]: is there an extra quote trailing the second item?
# '[[1465185600000,589.02,600.0,585.01,591.78,401760.0,67821.2330781393],[1465272000000,592.31,595.45,570.32,581.12,396206.0,67722.36141861044]]'
api_val = ast.literal_eval(api_return)
print(api_val[0][0])
# 1465185600000

How to check whether a json object is array

Im new to python.I came up with this issue while sending json arraylist obect from java to python.While sending the json object from java the json structure of the arraylist is
[{'firstObject' : 'firstVal'}]
but when i receive it in python i get the value as
{'listName':{'firstObject':'firstVal'}}
when i pass more than one object in the array like this :
[{'firstObject' : 'firstVal'},{'secondObject' : 'secondVal'}]
I am receiving the json from python end as
{'listName':[{'firstObject':'firstVal'},{'secondObject' : 'secondVal'}]}
I couldnt figure out why this is happening.Can anyone help me either a way to make the first case a array object or a way to figure out whether a json variable is array type.
Whenever you use the load (or loads) function from the json module, you get either a dict or a list object. To make sure you get a list instead of a dict containing listName, you could do the following:
import json
jsonfile = open(...) # <- your json file
json_obj = json.load(jsonfile)
if isinstance(json_obj, dict) and 'listName' in json_obj:
json_obj = json_obj['listName']
That should give you the desired result.
json module in Python does not change the structure:
assert type(json.loads('[{"firstObject": "firstVal"}]')) == list
If you see {'listName':{'firstObject':'firstVal'}} then something (either in java or in python (in your application code)) changes the output/input.
Note: it is easy to unpack 'listName' value as shown in #Fawers' answer but you should not do that. Fix the upstream code that produces wrong values instead.

Convert numpy.ndarray to list (Python)

I am running a function developed by Esri to get list of values in a integer column of a spatial table (however, the same behaviour is observed even when running the function on a non-spatial table). According to the help, I should get NumPy structured array. After running the function, I have a numpy array. I run print in this format:
in_table = r"C:\geodb101#server.sde\DataTable" #
data = arcpy.da.TableToNumPyArray(in_table, "Field3")
print data
Which gives me back this in IDE (copy/pasted from IDE interpreter):
[(20130825,) (20130827,) (20130102,)]
I am running:
allvalues = data.tolist()
and getting:
[(20130825,), (20130827,), (20130102,)]
Same result when running data.reshape(len(data)).tolist() as suggested in comments.
Running type() lets me know that in the first case it is <type 'numpy.ndarray'> and in the second case <type 'list'>. I am expecting to get my output list in another format [20130825, 20130827, 20130102]. What am I doing wrong or what else should I do to get the output list in the specified format?
I have a possible approach, but I'm not 100% sure it will work, as I can't figure out how you got tuples into an array (when I tried to create an array of tuples, it looks like the tuples got converted to arrays). In any case, give this a shot:
my_list = map(lambda x: x[0], my_np_array_with_tuples_in_it)
This assumes you're dealing specifically with the single element tuples you describe above. And like I said, when I tried to recreate your circumstances, numpy did some conversion moves that I don't fully understand (not really a numpy expert).
Hope that helps.
Update: Just saw the new edits. Not sure if my answer applies anymore.
Update 2: Glad that worked, here's a bit of elaboration.
Lambda is basically just an inline function, and is a construct common in a lot of languages. It's essentially a temporary, anonymous function. You could have just as easily done something like this:
def my_main_func():
def extract_tuple_value(tup):
return tup[0]
my_list = map(extract_tuple_value, my_np_array_with_tuples_in_it)
But as you can see, the lambda version is more concise. The "x" in my initial example is the equivalent of "tup" in the more verbose example.
Lambda expressions are generally limited to very simple operations, basically one line of logic, which is what is returned (there is no explicit return statement).
Update 3: After chatting with a buddy and doing some research, list comprehension is definitely the way to go (see Python List Comprehension Vs. Map).
From acushner's comment below, you can definitely go with this instead:
my_list = [tup[0] for tup in my_np_array_with_tuples_in_it]

json decode issue with bing data (python)

I am in trouble with the bing's json api.
Here is the json data i am receiving from api.bing.net/json.aspx:
{"SearchResponse":{"Version":"2.2","Query":{"SearchTerms":"news"},"Translation":{"Results":[{"TranslatedTerm":"Noticias"}]}}}
I need to parse the TranslatedTerm value "Noticias" but it seems i have a problem with the json decode. I am using this..
result = j.loads(bytes)
print result['SearchResponse']['Translation']['Results']
And python gives me this:
[{u'TranslatedTerm': u'Noticias'}]
If i add use it like this:
result['SearchResponse']['Translation']['Results']["TranslatedTerm"]
python raises an error like
print result['SearchResponse']['Translation']['Results']["TranslatedTerm"]
TypeError: list indices must be integers
How can i get the 'Noticias' as a plain string? Much appriciated...
The translation Results is a list - presumably because there can be many results.
If you're sure you're only interested in the first result, you can do this:
result['SearchResponse']['Translation']['Results'][0]['TranslatedTerm']

Categories

Resources