質問するログイン新規登録
Python

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

Q&A

解決済

1回答

488閲覧

Pythonで辞書データを2重ループにならずに処理したいです。

WatanabeJin

総合スコア44

Python

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

0グッド

0クリップ

投稿2022/03/04 10:47

0

0

行いたいこと

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

store = { "A店": {"リンゴ":5, "みかん":3, "もも": 1}, "B店": {"リンゴ": 3, "なし": 1}, "C店": {"いちご": 6, "みかん":1}, "D店": {"いちご":6, "リンゴ": 3, "なし": 2, "みかん":1} }

この辞書を以下のルールで分けていきます。

  1. お店ごとに品物をグループ分けする
  2. グループは合計5以下になるようにわける(ただし1つの品で5以上ならそのまま1グループにする)

A店の場合は リンゴで1グループ、みかんとももで1グループ
B店の場合はリンゴとなしで1グループ
C店の場合はいちごで1グループ、みかんで1グループ
D店の場合はいちごで1グループ、リンゴとなしで1グループ、みかんで1グループ

品物は数字で降順にソートされているとします。

最終的にはこのグループを以下のようなデータに変換したいです。

[ ["A店", "リンゴ"], ["A店", "みかん もも"], ["B店", "リンゴ なし"], ["C店", "いちご みかん"], ["D店", "いちご"], ["D店", "リンゴ なし"], ["D店", "みかん"] ]

このときに色々考えてみたのですが、2重ループになってしまい困っています。

どのようにすれば1回のループで実現できますでしょうか。

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

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

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

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

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

maisumakun

2022/03/04 11:03

> 2重ループになってしまい困っています。 なぜ困るのですか?
WatanabeJin

2022/03/04 11:05

いまはデータが3つなのですが、これは簡単に例題をするために行っています。 実際は1万以上のお店と、1万以上の品物があります。 ですので2重ループですと処理が遅くなってしまいます。
maisumakun

2022/03/04 11:12

> ですので2重ループですと処理が遅くなってしまいます。 実際に困る程度の速度しか出なかったのですか?
maisumakun

2022/03/04 11:14

> 実際は1万以上のお店と、1万以上の品物があります。 1万以上のお店全てに1万種類の商品がある、という状況なのですか?(そうだとしたらデータは1億項目になりますので、順当にたどっていっても時間がかかるのは「仕方ない」です)
guest

回答1

0

ベストアンサー

どのようにすれば1回のループで実現できますでしょうか。

無理でしょう。
速度が要求されるならC言語などで書いてはいかがでしょうか?
Pythonでは、ジェネレータにすればメモリを消費せずに高速になるかもしれません。

py

1stores = { 2 "A店": {"リンゴ":5, "みかん":3, "もも": 1}, 3 "B店": {"リンゴ": 3, "なし": 1}, 4 "C店": {"いちご": 6, "みかん":1}, 5 "D店": {"いちご":6, "リンゴ": 3, "なし": 2, "みかん":1} 6} 7 8def convert(limit=5): 9 for store, products in stores.items(): 10 names, counts = [], 0 11 for name, count in products.items(): 12 names.append(name) 13 counts += count 14 if counts >= limit: 15 yield store, " ".join(names) 16 names, counts = [], 0 17 if names: 18 yield store, " ".join(names) 19 20for item in convert(): 21 print(item)

投稿2022/03/04 15:22

編集2022/03/04 16:21
shiracamus

総合スコア5406

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問