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

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

新規登録して質問してみよう
ただいま回答率
85.35%
オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

2371閲覧

python forループをつかってdictに格納する方法について

pokemonta

総合スコア170

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/10/20 04:41

編集2020/10/20 13:33

Pythonプログラムで配列から取得したオブジェクトを
辞書型に格納することができない。
具体的にいいますと
resultから取得した配列0番目の {'name': 'yamada', 'weight': '72'}から
pythonプログラムでweightの値を取得して
キー weightとペアのマップ型で格納したいです。
しかしながら、構文エラーで実行することができません。対応方法をご教示願います。

ちなみに以下の構文なら成功しますが、
'weight' : r['weight'] for r in result
この書き方の場合、他の値(height)も取り出したい時に構文エラーになります。
仮にできたとしてもループが冗長だと思います。
'weight' : r['weight'] for r in result
'height' : r['height'] for r in result

result

1[ 2 {'name': 'yamada', 'month':'2020/10', 'weight': '72', 'height':180}, 3 {'name': 'yamada', 'month':'2020/11','weight': '74', 'height':181} 4]

※.resultはテーブルから取得した時系列データです

python

1 Item = [] 2 dict1 = { 3 'name' : 'yamada', 4 'DataList' : { 5 for value in result: 6 'weight' : value['weight'] 7 } 8 Item.append(dict1)

あるべき姿は以下の通りです。

json

1{ 2 "name": yamada, 3 "DataList":[ 4 { 5 "weight": '72' 6 }, 7 { 8 "weight": '74' 9 } 10 ] 11} 12

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sfdust

2020/10/20 09:29 編集

現状記載の内容の文章では、「あるべき結果」が具体的に分かりません。 ・なぜresultの中でyamadaが重複しているのか?重複しているキーをどのように扱うのか? ・heightはどこから出てきたのか?その扱いは? というところが明確になっていません。 したがって、上記の点を明確にするため、下記にこたえてください。 「 result = [ {'name': 'yamada', 'weight': '72', 'height':180}, {'name': 'yamada', 'weight': '74', 'height':182}, {'name': 'satou', 'weight': '54', 'height':170}, {'name': 'satou', 'weight': '58', 'height':172}, {'name': 'tanaka', 'weight': '42', 'height':149} ] が与えられ、プログラムを実行したとき 最終的に「Item」リストはどのような内容になっていてほしいのか?」
pokemonta

2020/10/20 07:01

すみません。割愛していました。 間に月が入るイメージです。 山田さんの7月の体重は、72kg。 つまり、時系列データなのです。
sfdust

2020/10/20 07:05 編集

それは文章ではなく、「与えられる具体的なresult」と、そのresultをプログラムで与えた結果の「あるべきItemの内容」という形で示してください。 現状の質問文のresultには「月」データが入っていないので、どう加工するべきか答えようにもこたえることはできません。 (「間に月が入るイメージ」と言われてもわかりません。resultのデータの中でどのように表現されているのか?) こちらで勝手にresultを想像して作っても質問者さんにとっては意味がないでしょう。
pokemonta

2020/10/20 07:05

★質問を訂正します。すみません。 {'name': 'yamada', 'month':'2020/10','weight': '72', 'height':180}, {'name': 'yamada', 'month':'2020/11','weight': '72', 'height':180}, {'name': 'yamada', 'month':'2020/12,'weight': '72', 'height':180}, nameとmonthがキーなら、このレコードは成立しています。(テーブルの1レコードです) レコードを引っ張ってきて nameとweightだけをJSONにしていましたが、heightも取得できるので これもJSONに追加することができます。
takutakuya

2020/10/20 07:29

質問は編集できるので、質問のほうを編集されたほうがいいですよ。
pokemonta

2020/10/20 07:36

アドバイスありがとうございます。 そのように致します
takutakuya

2020/10/20 08:09

他の値を取り出す時は、どういう形にしたいのでしょうか?
pokemonta

2020/10/20 10:06

result内のオブジェクトにname,weght,heigh,monthぐらいしか入りません。そのため、最終的には、DataListの一つの配列にweght,heigh,monthがdictで格納されます。
pokemonta

2020/10/20 10:08

ちなみに今は、便宜上DataListにweighしか記載してません。
takutakuya

2020/10/20 10:10

nameを抜いたほうが早いかもしれませんね
guest

回答1

0

ベストアンサー

データが下記のようになっていると仮定します。

result = [ {'name': 'yamada', 'weight': '72', 'height':'180'}, {'name': 'yamada', 'weight': '73', 'height':'180'}, {'name': 'yamada', 'weight': '75', 'height':'180'}, ]

処理用プログラムconvert関数は以下の通り

def convert(src, keywords): # 結果格納用の辞書 dest = dict() for src_item in src: # まずキーを登録する。 name = src_item.get('name') dest.setdefault("name", name) dest.setdefault("DataList", []) # DataListに格納する個別データ datalist_item = dict() for k, v in src_item.items(): if k in keywords: datalist_item.update({k: v}) if datalist_item: dest["DataList"].append(datalist_item) return dest

使用例

['weight', 'height']の2つを抽出対象として指定する。 ret = convert(result, ['weight', 'height']) # 以下は結果を整形して表示するため import json print(json.dumps(ret, indent=1))

出力結果

{ "name": "yamada", "DataList": [ { "weight": "72", "height": "180" }, { "weight": "73", "height": "180" }, { "weight": "75", "height": "180" } ] }

投稿2020/10/20 10:00

編集2020/10/20 10:09
sfdust

総合スコア1137

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pokemonta

2020/10/20 10:11

最終のアウトプットイメージは一致しています。 内容確認させていただきます。 なんで自分のプログラムでは、ダメかわかったりしますでしょうか?
pokemonta

2020/10/20 10:13

.getでしか取れないのでしょうか?
sfdust

2020/10/20 14:04 編集

>なんで自分のプログラムでは、ダメかわかったりしますでしょうか? Item = [] dict1 = { 'name' : 'yamada', 'DataList' : { 'weight' : value['weight'] for r in result } Item.append(dict1)」 だと 'weight' : value['weight'] for r in result はvalueという名前に束縛されているものがないためエラーになります。 'weight' : r['weight'] for r in result ならばOK。 でもheightは格納できません。 また、DataListはリストでないといけないのに、辞書になっている点で、仕様を満たしていません。
sfdust

2020/10/20 10:29 編集

>.getでしか取れないのでしょうか? get()で値を取得しているのは、指定したキーが存在しなかった場合にKeyErrorを発生させたくないからです。 name = src_item['name'] でも同じ動作になりますが、 nameというキーが存在しなかった場合、KeyErrorが発生します。 name = src_item.get('name')とした場合、KeyErrorは発生せずnameにはNoneが入ります。 (データとして"name"が存在しないことを想定していないならばどちらでも構いません)
pokemonta

2020/10/20 10:50

私のプログラムでシンタックスエラーとなっている箇所以下の部分です for value in result: 'weight' : value['weight'] この部分が腹落ちしないです。 今出先なのでご教示頂いた方法は帰宅後確認します
pokemonta

2020/10/20 12:51

ご教示頂いた方法では、 for k, v in src_item.items():の箇所で "errorType":"AttributeError","errorMessage":"'list' object has no attribute 'items'" が発生します。 src_itemは、srcを指します。src自体は、result ですのでListです。 Listには、items()操作がありませんので当然エラーとなります。 私の前段のコメントで、以下のようなリストから1要素を取り出して その要素の中でdict操作をするのが正解だと思うのですがなぜかエラーになります。
sfdust

2020/10/20 14:03 編集

質問文の記載通りに従えば、resultは、リストであり、かつ辞書を要素に持つリストです。 def convert(src, keywords): という関数を定義したうえで、 呼び出し時に、このconvert関数を下記のように呼び出しています。 ret = convert(result, ['weight', 'height']) つまりsrcに渡されるのは辞書を要素として持つリストresultです。 そして、convert関数の中で、 for src_item in src: としています。 これは、src(resultというリスト)の中の要素である 「{"name":"yamada",~~}」をsrc_itemとして渡す操作になります。 よってsrc_itemには、辞書{"name":"yamada",~~}が入ります。 辞書はitems()関数を持っているため、エラーにはならないはずですが・・・ エラーになる理由(推測): resultが result = [ {'name': 'yamada', 'weight': '72', 'height':'180'}, {'name': 'yamada', 'weight': '73', 'height':'180'}, {'name': 'yamada', 'weight': '75', 'height':'180'}, ] のような形になっていない。 または、 異なるプログラムを実行されているのどちらかだと思われます。
pokemonta

2020/10/20 13:44

成功しました。ありがとうございました。 私の当初書いたプログラムがなぜシンタックスエラーとなっていたかなんですが、 これはあくまでも推測ですが、 (ご指摘の「DataListはリストでないといけないのに、辞書になっている点で、仕様を満たしていません。」は一旦無視して頂いて) 以下のプログラムは成功します。 'DataList' : { 'weight' : r['weight'] for r in result } しかし、以下のプログラムは失敗します。 'DataList' : { for value in result: 'weight' : value['weight'] } 'DataList'は、dict型ですので、ロジックを入れれない(forループは入れれない。) 但し、 前者のリスト内包表記は例外?? だと理解しました。 ご教示頂いた方法は、箱の用意(List)と箱の中に入れる値(dict)の生成を分離しているので [for ループ] または、 {for ループ}をしていない点が上手くいっている利用かと思います
sfdust

2020/10/20 14:11 編集

>'DataList'は、dict型ですので、ロジックを入れれない(forループは入れれない。) 但し、 前者のリスト内包表記は例外?? だと理解しました。 その理解であっています。 辞書を作るときに{}の中に for文のような「文」を入れることは、文法上できません。 一方、内包表記はforを含んでいますが、全体として「文」ではなく、「式」というものになります。 式は、辞書の値として用いることができます。
pokemonta

2020/10/21 03:18

そうゆうことですね。その謎が解けんくて苦労しました。 貴重なお時間ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問