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

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

ただいまの
回答率

90.47%

  • Python 3.x

    6911questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python3で複数階層の辞書型を存在チェックして取得する方法

解決済

回答 1

投稿 編集

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

jnst

score 26

以下のような辞書型のオブジェクトがあるとします。
「token が存在すれば token の値を取得、なければ例外を出さずに None(undefined, nil) を取得」したいです。

obj = {
  "facebook": {
    "token": "xxx"
  },
  "twitter": {
  }
}

JavaScript で書くとこうなります

const fb = obj["facebook"] && obj["facebook"]["token"];  // => 'xxx'
const tw = obj["twitter"] && obj["twitter"]["token"];        // => undefined
const ig = obj["instgram"] && obj["instagram"]["token"]; // => undefined

Ruby なら Safe Navigation Operator があるのでもっとラクです

const fb = obj["facebook"]&.["token"];  # => 'xxx'
const tw = obj["twitter"]&.["token"];     # => nil
const ig = obj["instgram"]&.["token"];   # => nil

Python3 ではこのように書くしかないんでしょうか
非常に冗長で読みにくいです

const fb = obj["facebook"]["token"] if "facebook" in obj and "token" in obj["facebook"] else None    # => 'xxx'
const tw = obj["twitter"]["token"] if "twitter" in obj and "token" in obj["twitter"] else None              # => None
const ig = obj["instagram"]["token"] if "instagram" in obj and "token" in obj["instagram"] else None # => None


煩雑なのでもっと簡易な書き方があれば教えてください

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+7

getをつかうとKeyErrorを出しません。またなかった場合の代替値を指定できます。

facebookやtwitterという第一階層が必ずあるのであれば単に

obj['facebook'].get('token')  # ない場合はNone
obj['facebook'].get('token', 'notoken')  # ない場合はnotokenという文字列

でいけます。第一階層もあるか不定であれば

obj.get("facebook", {}).get("token")

みたいにするのもいいかもしれません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/06/05 13:38 編集

    最後のコードで一回目のget失敗時にdictを返さないといけないのが何か惜しいですね。単なるコメントですが。

    キャンセル

  • 2018/06/05 17:49

    一応`defaultdict`使えばそこも省略できますが、すこし混乱しそうなので控えました汗

    ```
    In [6]: from collections import defaultdict

    In [7]: data = defaultdict(dict)

    In [8]: data['facebook']['token'] = 'my token'

    In [9]: data['facebook'].get('token')
    Out[9]: 'my token'

    In [10]: data['twitter'].get('token')
    ```

    キャンセル

  • 2018/06/05 18:06 編集

    「なければ RuntimeError にならないように empty で初期化してから使う」というスニペットはスクリプト言語ではよく見るものなので、自分にとっては違和感ありませんでした👍

    obj.get("facebook", {}).get("token")

    これからこのコードを活用させてもらいます。

    キャンセル

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

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

関連した質問

  • 解決済

    ツイートの投稿

    大学で卒業研究としてTwitterAPIを利用したアプリケーションを開発しています。 その過程で以下のようにツイート投稿のところで行き詰まりました。 同じようなコードでタイムラ

  • 解決済

    ブラウザにてFacebook JavaScript SDKを使ってログインができない

    前提・実現したいこと ブラウザからFacebook JavaScript SDKを使ったFacebookのログイン機能を実装しようとしています。 しかし、ログインの処理でレスポ

  • 解決済

    facebookのいいねボタンについて

    最近になってfacebookのいいねボタンの仕様って変わりましたか? 最近、制作依頼されたサイトにfacebookのいいねボタンを設置したのですが、この前まではいいねを押した

  • 解決済

    Rubyでの文字列の連結がわかりません。

    前提・実現したいこと RubyでTwitterのbotを制作しています。ツイートしたい文字が「文字列+変数の中身」なのですが文字列の連結の方法がわかりません。 発生している問題

  • 解決済

    SNS認証プラグインにおけるuninitialized constantエラー

    今、開発中のサイトでSNS認証機能を実装したいです。 ユーザー登録時パスワードが不要になったりとユーザーにも運営側にもメリットがあるとわかりましたので取り組んでいます! 前

  • 解決済

    Devise内でomniauthのtwitter認証が完了してもレコードが格納されない

    前提・実現したいこと ///0222追記 すみません!そもそも「実現したい事」を書くのを忘れていました! エラーは後述の通り「Twitter認証後データがテーブルに格納されな

  • 解決済

    ツイッターのボタンを1個増やしたい

    【質問を修正しました】 ●使用している機能 CHROMEブラウザ公式ツイッター https://twitter.com/ ●使用したい機能および目的 拡張機能からJAVAscr

  • 解決済

    PythonでTwitterのタイムラインを取得

    お世話になります。 PythonでTwitterのタイムラインを取得したいです。 しかし下記のようにtwitter.getが働きません。 タイムラインの取得方法を教えて

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

  • Python 3.x

    6911questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。