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

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

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

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

Q&A

解決済

2回答

361閲覧

Pythonのアルゴリズムでどのように実装すれば良いのか答えがでません。

taku-s

総合スコア12

Python

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

0グッド

0クリップ

投稿2022/07/06 01:16

前提

Pythonでコードを書いています。
アルゴリズムに関して実現したいことがあるのですが、わかりそうでわからない為時間がかかっています。
是非お力添えいただきたいです。

実現したいこと

以下のリストを加工してまとめたいです。

python

1[ 2 {'ID': 1, 'fruits': 'りんご', 'total ': 1, 'product': ['青森'], 'counts': [1], 'remarks': ['酸味']}, 3 {'ID': 2, 'fruits': 'もも', 'total': 2, 'product': ['山梨'], 'counts': [2], 'remarks': ['甘味']}, 4 {'ID': 3, 'fruits': 'ぶどう', 'total': 1, 'product': ['山梨'], 'counts': [1], 'remarks': ['酸味']}, 5 {'ID': 2, 'fruits': 'もも', 'total': 1, 'product': ['福島'], 'counts': [1], 'remarks': ['甘味']}, 6 {'ID': 5, 'fruits': 'みかん', 'total': 1, 'product': ['愛媛'], 'counts': [1], 'remarks': ['うま味']}, 7 {'ID': 5, 'fruits': 'みかん', 'total': 3, 'product': ['和歌山'], 'counts': [3], 'remarks': ['酸味']}, 8 {'ID': 1, 'fruits': 'りんご', 'total': 2, 'product': ['福島'], 'counts': [2], 'remarks': ['酸味']}, 9 {'ID': 5, 'fruits': 'みかん', 'total': 2, 'product': ['静岡'], 'counts': [2], 'remarks': ['苦味']}, 10 ]
  • リスト内にdict型の値が入っています。
  • keyである"ID"が決まれば"fruits"も決まります。
  • 辞書型のkeyである'product''counts''remarks'の値はリスト型です。

纏めた結果は以下となります。

python

1[ 2 {'ID': 1, 'fruits': 'りんご', 'total': 3, 'product': ['青森', '福島'], 'counts': [1,2], 'remarks': ['酸味','酸味']}, 3 {'ID': 2, 'fruits': 'もも', 'total': 3, 'product': ['山梨', '福島'], 'counts': [2,1], 'remarks': ['甘味','甘味']}, 4 {'ID': 3, 'fruits': 'ぶどう', 'total': 1, 'product': ['山梨'], 'counts': [1], 'remarks': ['酸味']}, 5 {'ID': 5, 'fruits': 'みかん', 'total': 6, 'product': ['愛媛','和歌山','静岡'], 'counts': [1,3,2], 'remarks': ['うま味','酸味','苦味']}, 6 ]
  • 'ID'及び'fruits'が重複しないように辞書型をまとめ、'product''counts''remarks'の値をリストに追加していく。
  • countsの値であるリストの合計が'total'の合計となる。

該当のソースコード

python

1list = [ 2 {'ID': 1, 'fruits': 'りんご', 'total ': 1, 'product': ['青森'], 'counts': [1], 'remarks': ['酸味']}, 3 {'ID': 2, 'fruits': 'もも', 'total': 2, 'product': ['山梨'], 'counts': [2], 'remarks': ['甘味']}, 4 {'ID': 3, 'fruits': 'ぶどう', 'total': 1, 'product': ['山梨'], 'counts': [1], 'remarks': ['酸味']}, 5 {'ID': 2, 'fruits': 'もも', 'total': 1, 'product': ['福島'], 'counts': [1], 'remarks': ['甘味']}, 6 {'ID': 5, 'fruits': 'みかん', 'total': 1, 'product': ['愛媛'], 'counts': [1], 'remarks': ['うま味']}, 7 {'ID': 5, 'fruits': 'みかん', 'total': 3, 'product': ['和歌山'], 'counts': [3], 'remarks': ['酸味']}, 8 {'ID': 1, 'fruits': 'りんご', 'total': 2, 'product': ['福島'], 'counts': [2], 'remarks': ['酸味']}, 9 {'ID': 5, 'fruits': 'みかん', 'total': 2, 'product': ['静岡'], 'counts': [2], 'remarks': ['苦味']}, 10 ] 11new_list = [] 12for data in list: 13 for new_data in new_list: 14 if not data["ID"] in new_data["ID"]: 15 new_list.append({'ID':data["ID"],'fruits':data["fruits"]})

試したこと

⑴新たなリストnew_listを用意してlistをループで回す。
⑵new_listの中にlistのデータ”ID”と"fruits"がなければappendしていく。
⑶リストが回し終わったら、再度new_listを回し、counts内の数字を足してtotalの値を書き換える。
という流れになるとおもうのですが、⑴と⑵がうまく実装できません。

補足情報(FW/ツールのバージョンなど)

Python3.7.9を使用

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

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

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

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

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

guest

回答2

0

ベストアンサー

IDをキーとした辞書でフルーツ毎にデータをまとめると楽です。
この辞書にリストデータを順に登録あるいはproductなどの属性を追加していきます。
最後に辞書からリストを作成します。

Python

1lst = [ 2 {'ID': 1, 'fruits': 'りんご', 'total ': 1, 'product': ['青森'], 'counts': [1], 'remarks': ['酸味']}, 3 {'ID': 2, 'fruits': 'もも', 'total': 2, 'product': ['山梨'], 'counts': [2], 'remarks': ['甘味']}, 4 {'ID': 3, 'fruits': 'ぶどう', 'total': 1, 'product': ['山梨'], 'counts': [1], 'remarks': ['酸味']}, 5 {'ID': 2, 'fruits': 'もも', 'total': 1, 'product': ['福島'], 'counts': [1], 'remarks': ['甘味']}, 6 {'ID': 5, 'fruits': 'みかん', 'total': 1, 'product': ['愛媛'], 'counts': [1], 'remarks': ['うま味']}, 7 {'ID': 5, 'fruits': 'みかん', 'total': 3, 'product': ['和歌山'], 'counts': [3], 'remarks': ['酸味']}, 8 {'ID': 1, 'fruits': 'りんご', 'total': 2, 'product': ['福島'], 'counts': [2], 'remarks': ['酸味']}, 9 {'ID': 5, 'fruits': 'みかん', 'total': 2, 'product': ['静岡'], 'counts': [2], 'remarks': ['苦味']}, 10 ] 11 12fruits = dict() # IDをキーとしたフルーツ 13for row in lst: 14 # 存在しなければフルーツ追加 15 ID = row['ID'] 16 if ID not in fruits: 17 fruits[ID] = dict() 18 19 f = fruits[ID] 20 21 # 名称ない(=新規に追加)ならIDとともに取得 22 if 'fruits' not in f: 23 f['ID'] = ID 24 f['fruits'] = row['fruits'] 25 26 # 他の属性を追加 27 for key in ['product','counts','remarks']: 28 # 属性ない(=新規に追加)ならリスト生成 29 if key not in f: 30 f[key] = [] 31 32 f[key] += row[key] 33 34# countsからtotal算出 35for f in fruits.values(): 36 f['total'] = sum(f['counts']) 37 38# 辞書をリスト化 39ret = list(fruits.values()) 40for l in ret: 41 print(l) 42""" 43{'ID': 1, 'fruits': 'りんご', 'product': ['青森', '福島'], 'counts': [1, 2], 'remarks': ['酸味', '酸味'], 'total': 3} 44{'ID': 2, 'fruits': 'もも', 'product': ['山梨', '福島'], 'counts': [2, 1], 'remarks': ['甘味', '甘味'], 'total': 3} 45{'ID': 3, 'fruits': 'ぶどう', 'product': ['山梨'], 'counts': [1], 'remarks': ['酸味'], 'total': 1} 46{'ID': 5, 'fruits': 'みかん', 'product': ['愛媛', '和歌山', '静岡'], 'counts': [1, 3, 2], 'remarks': ['うま味', '酸味', '苦味'], 'total': 6} 47"""

投稿2022/07/06 02:00

can110

総合スコア38266

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

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

taku-s

2022/07/06 02:49

トレースしながら理解できました。ずっと自力で解決できそうでできなかったので、ようやくすっきりしました。 本当にありがとうございます。 確かにIDをキーとして辞書にすると理解がしやすかったです。このようなコードを自分で思いつくことができるようにこれからも精進します!
guest

0

既に解決済みですが、以下は itertools.groupby を使う方法です。

python

1from itertools import groupby 2from pprint import pprint 3 4lst = [ 5 {'ID': 1, 'fruits': 'りんご', 'total': 1, 'product': ['青森'], 'counts': [1], 'remarks': ['酸味']}, 6 {'ID': 2, 'fruits': 'もも', 'total': 2, 'product': ['山梨'], 'counts': [2], 'remarks': ['甘味']}, 7 {'ID': 3, 'fruits': 'ぶどう', 'total': 1, 'product': ['山梨'], 'counts': [1], 'remarks': ['酸味']}, 8 {'ID': 2, 'fruits': 'もも', 'total': 1, 'product': ['福島'], 'counts': [1], 'remarks': ['甘味']}, 9 {'ID': 5, 'fruits': 'みかん', 'total': 1, 'product': ['愛媛'], 'counts': [1], 'remarks': ['うま味']}, 10 {'ID': 5, 'fruits': 'みかん', 'total': 3, 'product': ['和歌山'], 'counts': [3], 'remarks': ['酸味']}, 11 {'ID': 1, 'fruits': 'りんご', 'total': 2, 'product': ['福島'], 'counts': [2], 'remarks': ['酸味']}, 12 {'ID': 5, 'fruits': 'みかん', 'total': 2, 'product': ['静岡'], 'counts': [2], 'remarks': ['苦味']}, 13] 14 15key = lambda x: x['ID'] 16lst.sort(key=key) 17result = [] 18for k, g in groupby(lst, key=key): 19 g = [*g] 20 result.append({ 21 'ID': k, 22 'fruits': g[0]['fruits'], 23 'total': sum(i['total'] for i in g), 24 'product': sum([i['product'] for i in g], []), 25 'counts': sum([i['counts'] for i in g], []), 26 'remarks': sum([i['remarks'] for i in g], []), 27 }) 28 29pprint(result, sort_dicts=False) 30 31# 32[{'ID': 1, 33 'fruits': 'りんご', 34 'total': 3, 35 'product': ['青森', '福島'], 36 'counts': [1, 2], 37 'remarks': ['酸味', '酸味']}, 38 {'ID': 2, 39 'fruits': 'もも', 40 'total': 3, 41 'product': ['山梨', '福島'], 42 'counts': [2, 1], 43 'remarks': ['甘味', '甘味']}, 44 {'ID': 3, 45 'fruits': 'ぶどう', 46 'total': 1, 47 'product': ['山梨'], 48 'counts': [1], 49 'remarks': ['酸味']}, 50 {'ID': 5, 51 'fruits': 'みかん', 52 'total': 6, 53 'product': ['愛媛', '和歌山', '静岡'], 54 'counts': [1, 3, 2], 55 'remarks': ['うま味', '酸味', '苦味']}]

投稿2022/07/06 03:10

melian

総合スコア19771

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

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

taku-s

2022/07/08 00:42

遅くなりまして申し訳ございません。 itertools、pprintこのようなものがあるのですね!知りませんでした。 他の方々のスクリプトを見るのは非常に参考になりますね、自分の血肉となるように精進いたします。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問