Python 辞書を更新して返す関数を作ったけど
「カロリーメイトとSOYJOYだけで夜飯を賄うにはどの種類をどれだけ食べれば良いか」という質問をYahoo知恵袋に投げるかで悩んでいる。
というのは置いといて、今回はPythonで辞書を更新して返す関数を作ったけど、もっとエレガントな書き方無いのかな〜というご相談。
追記
解決しました。
stackoverflow.com ここで書かれている
z = {**x, **y}
という表現が最強ですね。やはりpythonは英語でググるのがベストだなぁ。stack overflowのコミュニティが活発だなという印象。 ここも参考にしました。
背景としては、MicrosoftのText Analytics API (英語文章のネガポジ度などを解析するやーつ)を叩くプログラムを書いていて、jsonをPOSTするために辞書型にデータをいい感じに格納したいと思った感じ。
こういうjsonをPOSTしたい。
request = { "documents": [ {"language": "en", "id": 0, "text": "hogehoge"}, {"language": "en", "id": 1, "text": "fugafuga"}, ... {"language": "en", "id": 99, "text": "piyopiyo"} ] }
上の "language"
は全て "en"
で、"id"
はそれぞれユニークで、"text"
に解析する文字列を入れる。今回は解析する文字列はリストで translated_texts
に格納されているとする。(名前は気にしないで)
この translated_texts
リストを使って request
辞書をうま〜く作りたい。
documents_template = { "language": "en" } def return_updated_dic(dic, added_dic=None, **kwargs): new_dic = dic.copy() if added_dic: for k, v in added_dic.items(): new_dic.update({k: v}) else: for k, v in kwargs.items(): new_dic.update({k: v}) return new_dic added_dics = map(lambda x, y: {'text': x, 'id': y}, translated_texts, itertools.count(1)) documents = map(partial(return_updated_dic, documents_template), added_dics) request = { "documents": list(documents) } request_str = json_dumps(request)
(partialはfuctoosl.partial)
なんかね。自分でも周りくどいことしてるなと思う。
最終的には request["documents"]
にリストをぶちこみたいので、そのリスト documents
をどうやって作るか考えたんだけど、最近関数型っぽいプログラミングにはまっているので map
関数を使って作りたかったんです\(^o^)/。
だけど、pythonの辞書型はmutableなのでupdate()が破壊的メソッドであり、mapと相性が悪かった。悪いよね?だから新しく、return_updated_dicなる関数を作ってそれをmapに渡してる感じ。
これで一応望み通りの結果にはなるんだけど、もっとエレガントな書き方ないかな〜??なんか便利なライブラリあるとか?う〜ん。教えて。
普通にfor文を使えば
documents = [] for i, translated_text in enumerate(translated_texts): documents.append({"language": "en", "id": i, "text": translated_text})
で済む話なんだけど、、、笑 map使いたいねん。
(最近haskell入門しててそーゆー病気になったのかも)