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

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

新規登録して質問してみよう
ただいま回答率
85.40%
Python 3.x

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

Q&A

解決済

5回答

542閲覧

python:辞書の取り出し方について

mtpgah

総合スコア3

Python 3.x

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

0グッド

0クリップ

投稿2024/07/08 13:41

編集2024/07/10 12:26

以下のような辞書のリストがあります。

python

1fruit_dict = [ 2 {"商品名1":'みかん', 3 "価格1":"100円", 4 "産地1":'北海道'}, 5 {"商品名2":'りんご', 6 "価格2":"200円", 7 "産地2":'沖縄'}, 8 ]

上記から以下のような辞書をそれぞれ作りたいです。

python

1name = {"商品名1":'みかん',"商品名2":'りんご'} 2price = {"価格1":'りんご'"価格2":"200円"} 3production_area = {"産地1":'北海道', "産地2":'沖縄'}

それぞれkeyが違うし、辞書はインデックス番号を指定できないしで実装に悩んでいます。
初歩的な質問で恐縮ですが回答頂けますと幸いです。
よろしくお願いします。

#追記
皆様回答ありがとうございます。
上記の例では、商品1、商品2...
と共通部分で抽出しやすい形になっていますが、例えばこれが、AAA、BBB...
のように全く共通点の無いような場合を想定していました。
質問がわかりにくくて大変申し訳ありません。

#追記2(修正)
皆さま、大変参考になるアドバイスありがとうございます。
また、色々とお手数をお掛けして申し訳ございません。

python

1fruit_dict = [ 2 {"商品名1":'みかん',"商品名1":"100円", "商品名1":'沖縄'}, 3 {"商品名2":'りんご',"商品名2":"200円","商品名2":'沖縄'}, 4]

上記のように重複するkey若くは重複する値がある場合にも下記のような辞書にまとめることはできますでしょうか?

python

1name = {"商品名1":'みかん',"商品名2":'りんご'} 2price = {"商品名1":'100円'"商品名2":"200円"} 3production_area = {"商品名1":'沖縄', "商品名2":'沖縄'}

#追加3
"産地2"は"商品名2"でした。
申し訳ありません。
修正いたしました。

アドバイスありがとうございます。

python

1fruit_dict = [ 2{"商品名1": ['みかん', '100円', '沖縄']}, 3{"商品名2": ['りんご', '200円', '沖縄']}, 4]

上記辞書を作成して、以下のように修正出来たら良いなと思います。

python

1name = {"商品名1":'みかん',"商品名2":'りんご'} 2price = {"商品名1":'100円'"商品名2":"200円"} 3production_area = {"商品名1":'沖縄', "商品名2":'沖縄'}

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

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

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

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

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

melian

2024/07/08 13:46

price = {"商品名2":'りんご'"価格2":"200円"} となっていますが、これは、 price = {"価格1": '100円', "価格2": "200円"} ではないでしょうか?
mtpgah

2024/07/08 14:06

おっしゃる通りです。 修正いたしました。 ご指摘ありがとうございました。
pecmm

2024/07/08 17:17

> 例えばこれが、AAA、BBB... のように全く共通点の無いような場合を想定していました 全く共通点の無いキー同士をどうやって `name` や `price` に分類するのでしょうか? key名にルールが無い場合、項目の挿入順などでしょうか? もしくは、①価格は「~円」表記なので確定できる ②産地には地名が入っている(地名はプリセットに含まれるかの判定etc) ③前述の2つでなければ商品名 みたいに推理するとか? また、共通点がないということは逆にたまたま重複するような文字列が入っている可能性などもないでしょうか? 例 ``` {"商品名1":'みかん', "価格1":"100円", "産地1":'北海道'}, {"商品名2":'りんご', "価格2":"200円", "産地2":'沖縄'}, {"商品名称1":'ぶどう', ... {"商品名2":'いちご', ... //←りんご と重複 {"名称3":'林檎', ... ```
otn

2024/07/09 08:15 編集

> 例えばこれが、AAA、BBB...のように全く共通点の無いような場合を想定していました。 これだけだと意味不明なので、質問文に載っている商品名などの例と同じく、 「このデータを、こうしたい」と具体的に書いてください。 キーの値は無視して、順番だけ使いたいということですかね? 第1番目キーとその値の一覧 = {"AAA":'みかん',"BBB":'りんご'} みたいな?
otn

2024/07/09 14:05

> 例えばなのですが、辞書のキーが被る可能性もある前提ですとどのようにするのが良いでしょうか? そもそも何をしたいのか(このデータからこういう結果を得たいということ)が書かれていないので、 「キーか被る」など細かい話だけされてもいかんともしがたいです。 再度書きますが、 (1) 「このデータを、こうしたい」と具体的に書いてください。 (2) キーの値は無視して、順番だけ使いたいということですかね?
quickquip

2024/07/09 14:33 編集

> 下の例はキーが被ってる場合です。 >>> {"商品名1":'みかん', "商品名1":"100円", "商品名1":'北海道'} {'商品名1': '北海道'} となって **そのような辞書は作れない** ので意味のない仮定です。 また開き括弧が { なのが意図したものなのか不明ですし、閉じ括弧がないので文法的にも通りません。 すでにでていますが「辞書のキーが被る可能性もある前提」などという表現よりも、質問としては、 このようなデータを入力、こういう形に加工したい という形式が分かりやすくていいかと思います。(そもそも正しくPythonで扱えない形では駄目ですが)
melian

2024/07/10 12:12

> #追記2(修正) > 上記のように重複するkey若くは重複する値がある場合にも下記のような辞書にまとめることはできますでしょうか? 実際に fruit_dict を作成して内容を確認すると以下の様になります。キーが同じなので、最後の key-value ペア(産地)のみになってしまいます。商品名と価格の情報が欠落するので、記載されている様な結果に変形することができません。 $ python3 >>> fruit_dict = [ {"商品名1":'みかん', "商品名1":"100円", "商品名1":'沖縄'}, {"商品名2":'りんご', "商品名2":"200円", "商品名2":'沖縄'}, ] >>> fruit_dict [{'商品名1': '沖縄'}, {'商品名2': '沖縄'}] fruit_dict を以下の様に作成する場合は、期待される結果に変形することができます。(production_area = {"商品名1":'沖縄', "産地2":'沖縄'} と書かれていますが、"産地2"は"商品名2"でしょう) fruit_dict = [ {"商品名1": ['みかん', '100円', '沖縄']}, {"商品名2": ['りんご', '200円', '沖縄']}, ] もしくは、 fruit_dict = [ [{'商品名1': 'みかん'}, {'商品名1': '100円'}, {'商品名1': '沖縄'}], [{'商品名2': 'りんご'}, {'商品名2': '200円'}, {'商品名2': '沖縄'}], ]
mtpgah

2024/07/10 12:28

本文に追記させて頂きました。 fruit_dict = [ {"商品名1": ['みかん', '100円', '沖縄']}, {"商品名2": ['りんご', '200円', '沖縄']}, ] と記述し、これをそれぞれの辞書にまとめるのがスマートかなと思いました。 どのように行えば良いでしょうか? お手数をお掛けして申し訳ないです。
otn

2024/07/10 12:44 編集

(回答に書くつもりがコメントに書いてしまったので削除)
otn

2024/07/10 12:50

> と記述し、これをそれぞれの辞書にまとめるのがスマートかなと思いました。 なんと。 「入力データの形式は決まっているが、それをうまく説明できない」という状況かと思っていたのですが、 「入力データの形式は決まっておらず、どんな形式が良いかという相談」という質問だったのですか? 2024/07/10 21:28 のコメントの入力データだとして、出力データはどのようにしたいと言うことでしょうか? 書くの3度目ですが、 「このデータを、こうしたい」と具体的に書いてください。 もしかして、出力データの形式も決まっておらず、それも相談という質問なのでしょうか?
guest

回答5

0

要素の順番と個数が保証される、キーの被りはないという前提で

python

1name, price, production_area = map(dict, zip(*(d.items() for d in fruit_dict)))

でよいかと

もしくは

python

1name = {} 2price = {} 3production_area = {} 4for d in fruit_dict: 5 data = list(d.items()) # => [('商品名1', 'みかん'), ('価格1', '100円'), ('産地1', '北海道')] 6 name[data[0][0]] = data[0][1] 7 price[data[1][0]] = data[1][1] 8 production_area[data[2][0]] = data[2][1]

(追記)

辞書はインデックス番号を指定できないしで実装に悩んでいます。

list(dic.items()) で、"key-valueタプル"のリスト になりますよ


思考の経過は以下の通り

>>> fruit_dict = [ ... {"商品名1":'みかん', ... "価格1":"100円", ... "産地1":'北海道'}, ... {"商品名2":'りんご', ... "価格2":"200円", ... "産地2":'沖縄'}, ... ] >>> [list(d.items()) for d in fruit_dict] # itemsでバラバラに取り出す [[('商品名1', 'みかん'), ('価格1', '100円'), ('産地1', '北海道')], [('商品名2', 'りんご'), ('価格2', '200円'), ('産地2', '沖縄')]] >>> list(zip(*(d.items() for d in fruit_dict))) # zip(* )で転置 [(('商品名1', 'みかん'), ('商品名2', 'りんご')), (('価格1', '100円'), ('価格2', '200円')), (('産地1', '北海道'), ('産地2', '沖縄'))] >>> [{k: v for k, v in i} for i in zip(*(d.items() for d in fruit_dict))] # リスト内包で確認 [{'商品名1': 'みかん', '商品名2': 'りんご'}, {'価格1': '100円', '価格2': '200円'}, {'産地1': '北海道', '産地2': '沖縄'}] >>> [dict(i) for i in zip(*(d.items() for d in fruit_dict))] # 上と等価なことを確認 [{'商品名1': 'みかん', '商品名2': 'りんご'}, {'価格1': '100円', '価格2': '200円'}, {'産地1': '北海道', '産地2': '沖縄'}] >>> list(map(dict, zip(*(d.items() for d in fruit_dict)))) # map で dict にすれはよいことを確認 [{'商品名1': 'みかん', '商品名2': 'りんご'}, {'価格1': '100円', '価格2': '200円'}, {'産地1': '北海道', '産地2': '沖縄'}] >>> name, price, production_area = map(dict, zip(*(d.items() for d in fruit_dict))) # listを外して代入 >>> name {'商品名1': 'みかん', '商品名2': 'りんご'} >>> price {'価格1': '100円', '価格2': '200円'} >>> production_area {'産地1': '北海道', '産地2': '沖縄'}

投稿2024/07/08 15:12

編集2024/07/09 02:34
quickquip

総合スコア11165

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

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

0

ベストアンサー

#追加3

python

1fruit_dict = [ 2 {"商品名1": ['みかん', '100円', '沖縄']}, 3 {"商品名2": ['りんご', '200円', '沖縄']}, 4] 5 6name, price, production_area = map(dict, zip(*[[(k, i) for k, v in d.items() for i in v] for d in fruit_dict])) 7 8print(f'{name = }') 9print(f'{price = }') 10print(f'{production_area = }') 11 12# name = {'商品名1': 'みかん', '商品名2': 'りんご'} 13# price = {'商品名1': '100円', '商品名2': '200円'} 14# production_area = {'商品名1': '沖縄', '商品名2': '沖縄'}

投稿2024/07/08 14:27

編集2024/07/10 13:06
melian

総合スコア20255

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

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

0

キーの値は無視して、順番だけ使いたいということですかね?

に回答が無かったのですが、結局↑ということなのですかね?その前提で回答します。
まず、

Python

1fruit_dict = [ 2 {"商品名1":'みかん',"商品名1":"100円", "商品名1":'沖縄'}, 3 {"商品名2":'りんご',"商品名2":"200円","商品名2":'沖縄'}, 4]

のようにキーに重複があると、

Python

1fruit_dict = [ 2 {"商品名1":'沖縄'}, 3 {"商品名2":'沖縄'}, 4]

と同じになってしまい、おそらく意図通りで無いので、重複はないとします。
本当に重複があるなら、Pythonのdictでは実現できません。listのlistか、tupleのlistにするのですかね。

Python

1fruit_dict = [ 2 {"商品名1":'みかん',"商品名a":"100円","商品名A":'沖縄'}, 3 {"商品名2":'りんご',"商品名b":"200円","商品名B":'沖縄'}, 4] 5 6name, price, production_area = map(dict,zip(*[x.items() for x in fruit_dict])) 7print(name) 8#=> {'商品名1': 'みかん', '商品名2': 'りんご'} 9print(price) 10#=> {'商品名a': '100円', '商品名b': '200円'} 11print(production_area) 12#=> {'商品名A': '沖縄', '商品名B': '沖縄'}

dictitems()tuplelistに変えて、zip()で転置して、dict()でまたdictに戻してます。

投稿2024/07/10 12:43

otn

総合スコア85458

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

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

0

辞書のキー一覧を^商品名\d+$のような正規表現でピックアップすれば良いかと思います。

投稿2024/07/08 14:14

otn

総合スコア85458

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

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

0

べたなやりかたですが、こんな感じですかね。
if分の分岐はとりあえず、str.startswithを使っていますが、適当な判定処理にするといいでしょう。
工夫すれば短く書くこともできるでしょう。

python

1fruit_dict = [ 2 {"商品名1":'みかん', 3 "価格1":"100円", 4 "産地1":'北海道'}, 5 {"商品名2":'りんご', 6 "価格2":"200円", 7 "産地2":'沖縄'}, 8 ] 9 10name = {} 11price = {} 12production_area = {} 13 14for d in fruit_dict: 15 for k in d.keys(): 16 if k.startswith('商品名'): 17 name[k] = d[k] 18 elif k.startswith('価格'): 19 price[k] = d[k] 20 elif k.startswith('産地'): 21 production_area[k] = d[k] 22 else: 23 print(f'unknown class: {k}') 24 25print(name, price, production_area)

質問の追記を受けて追記

例えばこれが、AAA、BBB... のように全く共通点の無いような場合

にしても、コメントもついているとおり、何らかの判定方法が存在するはずなので、それをif文のところで使えばよいかと。

辞書はインデックス番号を指定できない

から逆に想像して辞書の順を考えているのかもしれませんが、言語仕様的には辞書は順を保持しないので、保存順で何かするべきでないと思います。

dictの代りにcollections.OrderdDictを使うということであればできますが、であれば、その元データからその性質を使って必要なデータを作るのがいいでしょう。

投稿2024/07/08 14:24

編集2024/07/09 02:57
TakaiY

総合スコア13337

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

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

bsdfan

2024/07/09 02:37

> 基本的に辞書は順を保持しないので、保存順で何かすることは不可能。 pythonの辞書で、挿入の順番が保持されるようになってかなり経つ(ver 3.6以降)ので、この書き方は誤解を招くと思います。
TakaiY

2024/07/09 02:54

ご指摘ありがとうございます。 cpythonの実装では3.6以降でそのとおりですが、言語仕様ではありませんし問題ないと思ってました。 少し修正しておきます。
quickquip

2024/07/09 03:17

3.6 では "実装の詳細" でしたが、3.7 で言語仕様になりましたよ 3.7 までが EoL に至ったいまでは「挿入の順番が保持される」と言ってよいと思ってます
TakaiY

2024/07/09 04:12

> 3.7 で言語仕様になりましたよ あら、そうだったんですね。 知りませんでした。 勉強します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問