2016-08-28 13 views
0

私はPythonには新しく、リストの理解を使用してJSONオブジェクトの値を配列に解析する最善の方法を見つけようとしています。ここでPythonリストの理解とJSONの解析

は私のコードです - 私は公に利用可能なiNaturalistのAPIを照会していると私はでこぼこ配列にJSONオブジェクトの特定の部分を取るように、それが返すJSONオブジェクトを利用したいと思います:

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&taxon_id=20856&per_page=200&order=desc&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'] 

このすべてが正常に動作し、次のような出力が得られます。私は次に何をしたいのですがどのような

9.5142456535,-83.8011438905 
10.2335478381,-84.8517773638 
10.3358965682,-84.9964271008 
10.3744851815,-84.9871494128 
10.2468720343,-84.9298072822 
... 

は、リストの内包とのforループを交換して、タプル内の位置値を格納しています。

[(long,lat) for i in range(n) for (long,lat) in obSet['results'][i]['location']] 

しかし、これは...任意の助けのおかげで動作しません:私は、私はそれがこのようなものだ推測しているという点で、構文に苦しんでいます。

+1

jsonの場所は*文字列*です。 –

+2

また、Pythonの初心者でもありますが、Python 3が** 8年間**リリースされたので、Python 2を使用する特別な理由はありますか? –

+0

Erm、抜群のポイント!私はおそらくそれを並べ替えることをお勧めします。 –

答えて

1

obSet['results']は、リスト、それを反復処理するためにrangeを使用する必要はありませんです

[item['location'] for item in obSet['results']] 

しかし、それぞれの場所は次のようにコーディングされていますfloatのリストまたはタプルではなく、文字列。適切な形式にそれを得るために、各部分がフロートに変換し、これらフロート座標の組を作り、区切り文字として,を使用して部品にitem['location']文字列を分割さ

[tuple(float(coord) for coord in item['location'].split(',')) 
for item in obSet['results']] 

を使用します。

>>> (long, lat) = obSet['results'][0]['location']

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: too many values to unpack 

さて、そのためには動作しませんでしたが、なぜ:

2

あなたが直接結果のリストを反復処理することができます。

print([tuple(result['location'].split(',')) for result in obSet['results']]) 
>> [('9.5142456535', '-83.8011438905'), ('10.2335478381', '-84.8517773638'), ... ] 
+0

あなたはタプルのリストではなく文字列のリストを返しています。 –

+0

'私が次にやりたいことは、forループをリスト内包に置き換え、その位置の値をタプルに格納することです。 ' - これはOPの要件です。 –

+0

@AhsanulHaqueが修正されました。 – DeepSpace

2
[tuple(obSet['results'][i]['location'].split(',')) for i in range(n)] 

これはタプルのリストを返し、タプルの要素はunicodeです。

あなたはフロートとしてタプルの要素は、次の操作を行うことにしたい場合:

[tuple(map(float,obSet['results'][i]['location'].split(','))) for i in range(n)] 
2

リスト内包なし[長い、LAT]のリストを取得するもう一つの方法:

In [14]: map(lambda x: obSet['results'][x]['location'].split(','), range(obSet['total_results'])) 
Out[14]: 
[[u'9.5142456535', u'-83.8011438905'], 
[u'10.2335478381', u'-84.8517773638'], 
[u'10.3358965682', u'-84.9964271008'], 
[u'10.3744851815', u'-84.9871494128'], 
... 

あなたの場合代わりにタプルのリストが必要です:

In [14]: map(lambda x: tuple(obSet['results'][x]['location'].split(',')), range(obSet['total_results'])) 
Out[14]: 
[[u'9.5142456535', u'-83.8011438905'], 
[u'10.2335478381', u'-84.8517773638'], 
[u'10.3358965682', u'-84.9964271008'], 
[u'10.3744851815', u'-84.9871494128'], 
... 

フロートにも変換する場合:

In [17]: map(lambda x: tuple(map(float, obSet['results'][x]['location'].split(','))), range(obSet['total_results'])) 
Out[17]: 
[(9.5142456535, -83.8011438905), 
(10.2335478381, -84.8517773638), 
(10.3358965682, -84.9964271008), 
(10.3744851815, -84.9871494128), 
(10.2468720343, -84.9298072822), 
(10.3456659939, -84.9451804822), 
... 
2

リスト内包にあなたのコードの直接の翻訳は次のとおりです。

positions = [obSet['results'][i]['location'] for i in range(obSet['total_results'])] 

obSet['total_results']は直接obSet['results']超える有益が、必要ではない、あなたは可能性だけのループであり、それぞれの結果の辞書を使用します。

positions = [res['location'] for res in obSet['results']] 

文字列のリストがありますが、それぞれ'location'はまだlong,lat以前に印刷した書式付き文字列。

スプリットその文字列や山車のシーケンスに結果を変換する:あなたははタプルを持たなければならない場合

>>> [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]] 

positions = [map(float, res['location'].split(',')) for res in obSet['results']] 

は今、あなたは浮動小数点値を持つリストのリストを持っていますリストではなくtuple()コールを追加してください:

positions = [tuple(map(float, res['location'].split(','))) 
      for res in obSet['results']] 

後者は、式がPython 3で動作することを保証します(map()はリストではなくイテレータを返します)。あなたはそれ以外の場合は、ネストされたリストの内包表記を使用する必要があると思います:

# produce a list of lists in Python 3 
positions = [[float(p) for p in res['location'].split(',')] for res in obSet['results']] 
+0

私は彼がPython 3を試してみた直後に 'map'を使ってOPを教えてくれてありがとうございます;) –

+0

@AnttiHaapala:' tuple() '呼び出しでうまく解決されます;-) –

1

タプルのリストを取得する方法を修正するには、リストの内包表記を使用すると、次のようになります。

def to_tuple(coords_str): 
    return tuple(coords_str.split(',')) 

output_list = [to_tuple(obSet['results'][i]['location']) for i in range(obSet['total_results'])] 

あなたはもちろんでto_tuple()を置き換えることができますラムダ関数、私は例を明確にしたかった。さらに、map()を使用すると、文字列の代わりに浮動小数点数を持つタプル(return tuple(map(float,coords_str.split(','))))を使用できます。

for item in obSet['results']: 
    print(item['location']) 

あなたが書くことができ、リストの内包表記にこれを行うには:

1

のは、これはわずか1つの場所で始まる、打撃を与えるしてみましょうか?これは、経度と緯度の座標がちょうど1つの文字列であるため、すぐにタプルとして展開することができないためです。最初に2つの異なる文字列に分割する必要があります。

>>> (long, lat) = obSet['results'][0]['location'].split(",")

ここから我々は0からnまでインデックス付けされている知っている結果、セット全体を反復処理することになるでしょう。 tuple(obSet['results'][i]['location'].split(","))は、インデックスiの結果の経度、緯度のタプルを返します。
>>> [tuple(obSet['results'][i]['location'].split(",")) for i in range(n)]
私たちが望むタプルのセットを与えるべきです。