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

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

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

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

Python

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

Q&A

解決済

2回答

6822閲覧

Python 辞書型で重複する値があった場合の結合について

AbcdefgFirst

総合スコア33

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2020/11/02 08:02

お世話になっております。

上のようなリストからitecCodeの値が同じであれば下にあるように[jan][DateId]にある値を結合したいのですが何か良い方法は無いでしょうか?

調べつつ色々試してみたのですが、うまく下記のように結合できる方法が実現出来なかったため何か良い方法があれば教えて頂けませんでしょうか。

宜しくお願い致します。

Python

1list = [ 2 {'itemCode': 'aaa', 3 'jan': '999999', 4 'DateId': '13'}, 5 {'itemCode': 'bbb', 6 'jan': '888888', 7 'DateId': '41'}, 8 {'itemCode': 'aaa', 9 'jan': '999991', 10 'DateId': '41'}, 11 {'itemCode': 'ccc', 12 'jan': '777777', 13 'DateId': '38'} 14]

実現したいもの

Python

1list = [ 2 {'itemCode': 'aaa', 3 'jan': [999999,999991], 4 'DateId': [13,41]}, 5 {'itemCode': 'bbb', 6 'jan': '888888', 7 'DateId': '41'}, 8 {'itemCode': 'ccc', 9 'jan': '777777', 10 'DateId': '38'} 11] 12

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

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

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

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

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

LouiS0616

2020/11/02 08:08 編集

実際に試したコードを追記して下さい。 どんな方法をどのように試してどのように失敗したのか読み取れません。
guest

回答2

0

ベストアンサー

DataFrameにする方法は既出なので、リストでチマチマやる方法。

新しいリストにappendしつつ、すでに同じitemCodeが新しいリストに存在するときには、janとDateIdの値をappendする(janとDateIdの値がリストでない場合はリスト化も行なう)。

Python

1lst = [ 2 {'itemCode': 'aaa', 'jan': '999999', 'DateId': '13'}, 3 {'itemCode': 'bbb', 'jan': '888888', 'DateId': '41'}, 4 {'itemCode': 'aaa', 'jan': '999991', 'DateId': '41'}, 5 {'itemCode': 'ccc', 'jan': '777777', 'DateId': '38'} 6] 7 8new_lst = [] 9for dic in lst: 10 for dic2 in new_lst: 11 if dic['itemCode'] == dic2['itemCode']: 12 if type(dic2['jan']) is not list: 13 dic2['jan'] = [dic2['jan']] 14 dic2['jan'].append(dic['jan']) 15 16 if type(dic2['DateId']) is not list: 17 dic2['DateId'] = [dic2['DateId']] 18 dic2['DateId'].append(dic['DateId']) 19 break 20 else: 21 new_lst.append(dic) 22 23print(new_lst)

result

1[{'itemCode': 'aaa', 'jan': ['999999', '999991'], 'DateId': ['13', '41']}, {'itemCode': 'bbb', 'jan': '888888', 'DateId': '41'}, {'itemCode': 'ccc', 'jan': '777777', 'DateId': '38'}]

投稿2020/11/02 09:09

Daregada

総合スコア11990

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

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

AbcdefgFirst

2020/11/04 01:45

ご回答ありがとうございます! 頂いたコードを試したところ希望通りの出力になりました。 最後のelseの部分が分からないのですが、同じインデントにifが無い場合も使用出来るのでしょうか? elseを外してインデントを1つ浅くしたところ、同じitemCodeの商品があった場合にjan、DateIdをリストにはまとめられたのですが、その商品分もnew_lstにも値が追加されてしまいました。
Daregada

2020/11/04 03:13

最後のelseは、他の言語ではあまり見かけない「forに対するelse」です。 途中でbreakしないでforループを最後まで処理したときにだけelse以下が実行されます。
AbcdefgFirst

2020/11/04 23:40

ありがとうございます。 このような書き方は知らなかったので勉強になりました(_ _)
guest

0

itertools.groupby なども検討しましたが、pandas の DataFrame にして、希望する形式に変更してから、再度 dict に戻すのが簡単そうです。

  1. dict を DataFrame にする
  2. groupby("itemCode").aggregate(list)itemCode が同じ要素はまとめる
  3. (もし必要であれば)要素が1つしかないものはリストを外す。['888888'] のように要素が1つのリストになってもよいのであればこの処理は不要。
  4. to_dict("records") で dict に戻す。

python

1import pandas as pd 2from pprint import pprint 3 4lst = [ 5 {"itemCode": "aaa", "jan": "999999", "DateId": "13"}, 6 {"itemCode": "bbb", "jan": "888888", "DateId": "41"}, 7 {"itemCode": "aaa", "jan": "999991", "DateId": "41"}, 8 {"itemCode": "ccc", "jan": "777777", "DateId": "38"}, 9] 10 11 12df = pd.DataFrame(lst) 13 14# itemCode が同じ辞書をまとめる。 15ret = df.groupby("itemCode").aggregate(list).reset_index() 16 17# 要素が1つしかないものはリストを外す。 18ret = ret.applymap(lambda x: x[0] if isinstance(x, list) and len(x) == 1 else x) 19 20# dict にする。 21ret = ret.to_dict("records") 22 23pprint(ret) 24# [{'DateId': ['13', '41'], 'itemCode': 'aaa', 'jan': ['999999', '999991']}, 25# {'DateId': '41', 'itemCode': 'bbb', 'jan': '888888'}, 26# {'DateId': '38', 'itemCode': 'ccc', 'jan': '777777'}]

投稿2020/11/02 08:38

tiitoi

総合スコア21956

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

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

AbcdefgFirst

2020/11/04 01:39

ご回答ありがとうございます! Pandasは使った事が無いのですが頂いたコードを試したところ動作致しました。 今後の参考にさせて頂きたいと思います。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問