質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.61%

最寄駅のjsonデータから重複する駅(値)を除いて整理する

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 765

G350

score 13

 前提・実現したいこと

初めて質問させていただきます。
Python3で現在地から最寄駅の情報を表示するシステムを作っています。
緯度経度でリクエストすると、最寄駅情報が帰ってくるAPIを利用しています。

APIのサンプル
http://express.heartrails.com/api/json?method=getStations&x=139.7505027&y=35.7048605

レンスポンス

[{'distance': '360m',  'line': '東京メトロ南北線',  'name': '後楽園',  'next': '東大前',  'postal': '1120002',  'prefecture': '東京都',  'prev': '飯田橋',  'x': 139.751864,  'y': 35.707898},
 {'distance': '360m',  'line': '東京メトロ丸ノ内線',  'name': '後楽園',  'next': '本郷三丁目',  'postal': '1120003',  'prefecture': '東京都',  'prev': '茗荷谷',  'x': 139.751864,  'y': 35.707898},
 {'distance': '450m',  'line': '都営三田線',  'name': '水道橋',  'next': '春日',  'postal': '1130033',  'prefecture': '東京都',  'prev': '神保町',  'x': 139.75516,  'y': 35.703398},
 {'distance': '470m',  'line': 'JR中央線',  'name': '水道橋',  'next': '飯田橋',  'postal': '1010061',  'prefecture': '東京都',  'prev': '御茶ノ水',  'x': 139.754312,  'y': 35.702039},
・・・
以下略

上記のレスポンスデータから、↓ここまでは自分で取得できました。

'東京メトロ南北線 後楽園駅 360m',
'東京メトロ丸ノ内線 後楽園駅 360m',
'都営三田線 水道橋駅 450m',
'JR中央線 水道橋駅 470m',
'JR総武線 水道橋駅 470m',
'東京メトロ東西線 飯田橋駅 540m',


【最終的にやりたいこと】

駅名と距離が同じ場合は以下のようにまとめたいです。
距離が近いものから順に表示したいです。

'東京メトロ南北線・丸ノ内線 後楽園駅 360m', #同じメトロなので、まとめる
'都営三田線 水道橋駅 450m',
'JR中央線・総武線 水道橋駅 470m', #同じJRなので、まとめる
'東京メトロ東西線 飯田橋駅 540m',

↓こちらでも構いません。

'東京メトロ南北線ほか 後楽園駅 360m', #同じメトロなので、最初の路線だけ表記して、「ほか」を追加
'都営三田線 水道橋駅 450m', 
'JR中央線ほか 水道橋駅 470m', #同じJRなので、最初の路線だけ表記して、「ほか」を追加
'東京メトロ東西線 飯田橋駅 540m',

 該当のソースコード

以下のようなif文をfor rangeで回したりしているのですが、思うような結果が得られずに困っています。
もっとスマートな方法があると思いますが、これしか思いつかずで、、、

#駅同じ・距離同じ場合
if 駅 == 駅+1 and 距離 == 距離+1:
    処理1

#駅同じ・距離が違う場合 
if 駅 == 駅+1 and 距離 != 距離+1:
    処理2

#駅違う・距離同じ場合    
if 駅 != 駅+1 and 距離 == 距離+1:
    処理3

#駅違う・距離違う場合    
else:
    処理4

 試したこと

zip()やenumerate()なども検討しましたが、どうにも正解にたどり着けませんでした。
どうかお力をお貸しいただけないでしょうか。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

「同じメトロなので」とか「同じJRなので」という条件でまとめようとすると、おそらく正確に行うには運営主体対路線名をすべて網羅したデータベースが必要になるかと。ちょっと現実的ではありません。

位置、あるいは距離と駅名が一致していれば同じ場所とみなす、程度であれば簡単に行なえます。

下に示す程度の出力フォーマットで妥協できれば、幸せはすぐそこにあります。

  • 後楽園駅 360m
    東京メトロ南北線
    東京メトロ丸ノ内線
  • 水道橋駅 450m
    都営三田線
  • 水道橋駅 470m
    JR中央線
    JR総武線
  • 飯田橋駅 540m
    東京メトロ東西線

あとは文字列処理で先頭の一致部分は省略するとか、そういったセコい方法でやれなくはありませんが。どんな路線名でも正しく処理してくれるという保証はありません。


駅名と距離が同じ場合は以下のようにまとめたい

とりあえず駅名と距離をキーに、駅の情報のlistを値に入れた辞書を作ってみました。

from collections import defaultdict

import requests

r = requests.get("http://express.heartrails.com/api/json?method=getStations&x=139.7505027&y=35.7048605")
data = r.json()["response"]["station"]

d = defaultdict(list)
for sttn in data:
    d[(sttn["name"], sttn["distance"])].append(sttn)

for k,v in d.items():
    print(k, v)
""" =>
('飯田橋', '540m') [{'prev': '神楽坂', 'next': '九段下', 'prefecture': '東京都', 'line': '東京メトロ東西線', 'x': 139.745986, 'postal': '1020072', 'y': 35.701725, 'distance': '540m', 'name': '飯田橋'}, {'prev': '牛込神楽坂', 'next': '春日', 'prefecture': '東京都', 'line': '都営大江戸線', 'x': 139.744999, 'postal': '1120004', 'y': 35.702927, 'distance': '540m', 'name': '飯田橋'}]
('水道橋', '470m') [{'prev': '御茶ノ水', 'next': '飯田橋', 'prefecture': '東京都', 'line': 'JR中央線', 'x': 139.754312, 'postal': '1010061', 'y': 35.702039, 'distance': '470m', 'name': '水道橋'}, {'prev': '飯田橋', 'next': '御茶ノ水', 'prefecture': '東京都', 'line': 'JR総武線', 'x': 139.754312, 'postal': '1010061', 'y': 35.702039, 'distance': '470m', 'name': '水道橋'}]
('水道橋', '450m') [{'prev': '神保町', 'next': '春日', 'prefecture': '東京都', 'line': '都営三田線', 'x': 139.75516, 'postal': '1130033', 'y': 35.703398, 'distance': '450m', 'name': '水道橋'}]
('後楽園', '360m') [{'prev': '飯田橋', 'next': '東大前', 'prefecture': '東京都', 'line': '東京メトロ南北線', 'x': 139.751864, 'postal': '1120002', 'y': 35.707898, 'distance': '360m', 'name': '後楽園'}, {'prev': '茗荷谷', 'next': '本郷三丁目', 'prefecture': '東京都', 'line': '東京メトロ丸ノ内線', 'x': 139.751864, 'postal': '1120003', 'y': 35.707898, 'distance': '360m', 'name': '後楽園'}]
"""

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/05 20:59

    コード付きのご回答ありがとうございます!
    ご提案いただいた結果で問題ございませんでした。

    数日悩んでいたので、本当に助かりました。
    defaultdictを使いこなせるように頑張ってみます。

    キャンセル

0

最初の集計単位をx,yでやればよいのでは?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/05 20:55

    ありがとうございます、初心者なのでx,yをどのように利用するかが思いつきませんでした。
    下記のコードで解決いたしましたので、Pythonを使い方を深めていこうと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る