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

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

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

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

Q&A

解決済

3回答

242閲覧

pythonの内包表記で、リストを含むディクショナリのデータを作成する方法

kazuya_

総合スコア78

Python

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

1グッド

1クリップ

投稿2024/03/13 08:01

実現したいこと

内包表記で、リストを含むディクショナリのデータを作成する方法について知りたい

発生している問題・分からないこと

内包表記でない下記コード例の出力を出したいです。
内包表記でディクショナリのキーまで重複せずに出るのですが、
そのキーに属するデータをリスト化できませんでした。

該当のソースコード

python

1from dataclasses import dataclass 2from collections import defaultdict 3 4@dataclass 5class placeSort: 6 num : int 7 place: str 8 9pls = [] 10pls.append(placeSort(num = 3 ,place = 'A')) 11pls.append(placeSort(num = 3 ,place = 'B')) 12pls.append(placeSort(num = 3 ,place = 'A')) 13pls.append(placeSort(num = 2 ,place = 'C')) 14pls.append(placeSort(num = 2 ,place = 'D')) 15pls.append(placeSort(num = 1 ,place = 'E')) 16 17#<内包表記でない例> 18res0=defaultdict(list) 19lbuf = list() 20for item in pls: 21 if res0.get(item.num) == None: 22 lbuf = list() 23 lbuf.append(item.place) 24 res0[item.num]=lbuf 25 else: 26 lbuf =res0.get(item.num) 27 lbuf.append(item.place) 28 res0[item.num]=lbuf 29print(res0) 30#出したい出力 31# defaultdict(<class 'list'>, {3: ['A', 'B', 'A'], 2: ['C', 'D'], 1: ['E']} 32 33<内包表記で、できたところまで> 34#キーの一覧をだす 35res1 = [z for z in {x.num for x in pls}] 36print(res1) 37# [1, 2, 3] 38 39#キーの一覧毎の、リストをまとめたいができません 40res2 = [(z,y.place) for y in pls for z in {x.num for x in pls} if y.num==z] 41print(res2) 42#[(3, 'A'), (3, 'B'), (3, 'A'), (2, 'C'), (2, 'D'), (1, 'E')] 43

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

res2の出力まで出しましたが、リスト化できませんでした。

補足

特になし

melian👍を押しています

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

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

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

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

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

quickquip

2024/03/13 09:12 編集

XY問題 https://ja.meta.stackoverflow.com/questions/2701/#answer-2702 になっていて、 defaultdictやsetdefaultを使ってfor文で書くのが正着で**内包表記で書くべきではない(書けない)** 処理にしか思えないので「なぜ内包表記で書きたいのか?」が欲しい気がします。ただの気分でないなら、質問者さんに必要な回答を書くためにはその理由の方が大事になるかと
kazuya_

2024/03/14 01:23

ご回答ありがとうございます。 dict型を今まで、使用していましたが、dataclassを代わりに使用して便利にデータを 管理できないかと考えたのが発端です。setdeaultを使用すると簡単にできることを知りませんでした。 ありがとうございます。
guest

回答3

0

内包表記で捨てるリストを生成していることや事前ソートしているのが無駄な処理で

python

1res0 = defaultdict(list) 2for item in pls: 3 res0[item.num].append(item.place)

python

1res0 = {} 2for item in pls: 3 res0.setdefault(item.num, []).append(item.place)

でよいと思います。

投稿2024/03/14 04:12

編集2024/03/17 04:25
quickquip

総合スコア11038

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

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

0

解決済みですが、単純に辞書内包表記を使用した例です。ご参考までに提示します。

Python

1from dataclasses import dataclass 2 3@dataclass 4class placeSort: 5 num : int 6 place: str 7 8pls = [] 9pls.append(placeSort(num = 3 ,place = 'A')) 10pls.append(placeSort(num = 3 ,place = 'B')) 11pls.append(placeSort(num = 3 ,place = 'A')) 12pls.append(placeSort(num = 2 ,place = 'C')) 13pls.append(placeSort(num = 2 ,place = 'D')) 14pls.append(placeSort(num = 1 ,place = 'E')) 15 16res = {k:[p.place for p in pls if p.num==k] for k in 17 sorted(set(p.num for p in pls), reverse=True)} 18print(res) # {3: ['A', 'B', 'A'], 2: ['C', 'D'], 1: ['E']}

投稿2024/03/16 13:08

lehshell

総合スコア1147

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

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

0

ベストアンサー

#出したい出力
# defaultdict(<class 'list'>, {3: ['A', 'B', 'A'], 2: ['C', 'D'], 1: ['E']}

python

1from dataclasses import dataclass 2from collections import defaultdict 3 4@dataclass 5class placeSort: 6 num : int 7 place: str 8 9pls = [] 10pls.append(placeSort(num = 3 ,place = 'A')) 11pls.append(placeSort(num = 3 ,place = 'B')) 12pls.append(placeSort(num = 3 ,place = 'A')) 13pls.append(placeSort(num = 2 ,place = 'C')) 14pls.append(placeSort(num = 2 ,place = 'D')) 15pls.append(placeSort(num = 1 ,place = 'E')) 16 17## 18res = {} 19[res.setdefault(p.num, []).append(p.place) for p in pls] 20print(res) 21 22# {3: ['A', 'B', 'A'], 2: ['C', 'D'], 1: ['E']}

追記

itertools.groupby() を使う場合。

python

1from itertools import groupby 2 3keyfunc = lambda p: p.num 4res = {k: [p.place for p in g] for k, g in groupby(sorted(pls, key=keyfunc), key=keyfunc)} 5print(res) 6 7# {1: ['E'], 2: ['C', 'D'], 3: ['A', 'B', 'A']}

投稿2024/03/13 08:23

編集2024/03/13 16:46
melian

総合スコア19816

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

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

kazuya_

2024/03/14 01:25

いろいろ有効な方法、ご回答ありがとうございました。 便利ですね。慣れないとわかりにくいですが、活用させていただきます。 今後とも、よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問