Python List comprehension and JSON parsing
<p>I'm new to Python and trying to figure out the best way to parse the values of a JSON object into an array, using a list comprehension. </p>

<p>Here is my code - I'm querying the publicly available iNaturalist API and would like to take the JSON object that it returns, so that I take specific parts of the JSON object into a bumpy array:</p>

<pre><code>import json
import urllib2

#Set Observations URL request for Resplendent Quetzal of Costa Rica
query = urllib2.urlopen("http://api.inaturalist.org/v1/observations?place_id=6924&amp;taxon_id=20856&amp;per_page=200&amp;order=desc&amp;order_by=created_at")
obSet = json.load(query)

#Print out Lat Long of observation
n = obSet['total_results']

for i in range(n) :
    print obSet['results'][i]['location'] 
</code></pre>

<p>This all works fine and gives the following output:</p>

<pre><code>9.5142456535,-83.8011438905
10.2335478381,-84.8517773638
10.3358965682,-84.9964271008
10.3744851815,-84.9871494128
10.2468720343,-84.9298072822
...
</code></pre>

<p>What I'd like to do next is replace the for loop with a list comprehension, and store the location value in a tuple. I'm struggling with the syntax in that I'm guessing it's something like this:</p>

<pre><code>[(long,lat) for i in range(n) for (long,lat) in obSet['results'][i]['location']]
</code></pre>

<p>But this doesn't work...thanks for any help.</p>

<p>The direct translation of your code into a list comprehension is:</p>

<pre><code>positions = [obSet['results'][i]['location'] for i in range(obSet['total_results'])]
</code></pre>

<p>The <code>obSet['total_results']</code> is informative but not needed, you could just loop over <code>obSet['results']</code> directly and use each resulting dictionary:</p>

<pre><code>positions = [res['location'] for res in obSet['results']]
</code></pre>

<p>Now you have a list of <em>strings</em> however, as each <code>'location'</code> is still the <code>long,lat</code> formatted string you printed before.</p>

<p>Split that string and convert the result into a sequence of floats:</p>

<pre><code>positions = [map(float, res['location'].split(',')) for res in obSet['results']]
</code></pre>

<p>Now you have a list of lists with floating point values:</p>

<pre><code>&gt;&gt;&gt; [map(float, res['location'].split(',')) for res in obSet['results']]
[[9.5142456535, -83.8011438905], [10.2335478381, -84.8517773638], [10.3358965682, -84.9964271008], [10.3744851815, -84.9871494128], [10.2468720343, -84.9298072822], [10.3456659939, -84.9451804822], [10.3611732346, -84.9450302597], [10.3174360636, -84.8798676791], [10.325110706, -84.939710318], [9.4098152454, -83.9255607577], [9.4907141714, -83.9240819199], [9.562637289, -83.8170178428], [9.4373885911, -83.8312881263], [9.4766746409, -83.8120952573], [10.2651190176, -84.6360466565], [9.6572995298, -83.8322965118], [9.6997991784, -83.9076919066], [9.6811177044, -83.8487647156], [9.7416717045, -83.929327673], [9.4885099275, -83.9583968683], [10.1233252667, -84.5751029683], [9.4411815757, -83.824401543], [9.4202687169, -83.9550344212], [9.4620656621, -83.665183105], [9.5861809119, -83.8358881552], [9.4508914243, -83.9054016165], [9.4798058284, -83.9362558497], [9.5970449879, -83.8969131893], [9.5855562829, -83.8354434596], [10.2366179555, -84.854847472], [9.718459702, -83.8910277016], [9.4424384874, -83.8880459793], [9.5535916157, -83.9578166199], [10.4124554163, -84.9796942349], [10.0476688795, -84.298227929], [10.2129436252, -84.8384097435], [10.2052632717, -84.6053701877], [10.3835784147, -84.8677930134], [9.6079669672, -83.9084281155], [10.3583643315, -84.8069762134], [10.3975986735, -84.9196996767], [10.2060835381, -84.9698814407], [10.3322929317, -84.8805587129], [9.4756504472, -83.963818143], [10.3997876964, -84.9127311339], [10.1777433853, -84.0673088686], [10.3346128571, -84.9306278215], [9.5193346195, -83.9404786293], [9.421538224, -83.7689452093], [9.430427837, -83.9532672942], [10.3243212895, -84.9653175843], [10.021698503, -83.885674888]]
</code></pre>

<p>If you <em>must</em> have tuples rather than lists, add a <code>tuple()</code> call:</p>

<pre><code>positions = [tuple(map(float, res['location'].split(',')))
             for res in obSet['results']]
</code></pre>

<p>The latter also makes sure the expression works in Python 3 (where <code>map()</code> returns an iterator, not a list); you'd otherwise have to use a nested list comprehension:</p>

<pre><code># produce a list of lists in Python 3
positions = [[float(p) for p in res['location'].split(',')] for res in obSet['results']]
</code></pre>

python json list-comprehension