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

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

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

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

Q&A

解決済

2回答

510閲覧

辞書を小さいもの順にソートしたい

k0908

総合スコア102

Python

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

0グッド

0クリップ

投稿2018/05/10 03:20

辞書を小さいもの順にソートしたい。
df変数に

{"A": [{"a": 100}, {"b": 200}, {"c": 300}], "B": [{"a": 400}, {"b": 500}, {"c": 80}], "C": [{"a": 340}, {"b": 600}, {"c": 130}], "D": [{"a": 250}, {"b": 390}, {"c": 220}]}

と内容が入っている。
このdf辞書をソートして

A→ a: 100 b: 200 c: 300 B→ c: 80 a: 400 b: 500 C→ c: 130 a: 340 b: 600 D→ c: 220 a: 250 b: 390

のように出力したい。

for key, value in sorted(results.items()): print( key + "→") for ky,vl in sorted((ky, vl) for ky,vl in value.items(), key=lambda x: x[1]): print(ky + ":" + vl)

とコードを書いて実行すると、
SyntaxError: Generator expression must be parenthesized if not sole argument
とエラーが出た。
何が間違っているのだろうか?

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

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

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

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

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

quickquip

2018/05/10 04:14

エラーメッセージを読んだのでしょうか?
guest

回答2

0

python

for key, value in sorted(results.items()):
print( key + "→")
for ky,vl in sorted((ky, vl) for ky,vl in value.items(), key=lambda x: x[1]):
print(ky + ":" + vl)

とコードを書いて実行すると、
SyntaxError: Generator expression must be parenthesized if not sole argument
とエラーが出た。
何が間違っているのだろうか?

ジェネレータ式とは本来リスト内包表記の外側を丸かっこに変えた見た目のものですが、pythonには関数の中に単一の引数として渡される場合は丸かっこを省略して書くことができるという糖衣構文があります。

今回はsorted関数に他の引数(key)を指定しているので駄目です。

これを直すと、こうなります(ついでにインデントも修正)。

python

1for key, value in sorted(results.items()): 2 print( key + "→") 3 for ky,vl in sorted(((ky, vl) for ky,vl in value.items()), key=lambda x: x[1]): 4 print(ky + ":" + vl)

これは3行目でAttributeError: 'list' object has no attribute 'items'が出ます。しょうがないですね。valueはlistなので。

データ構造を変えるのがスジですが、そっちの回答はLouiS0616さんが載せているので、敢えてそのままやるとすると、こうかな。

python

1for key, value in sorted(results.items()): 2 print( key + "→") 3 for ky,vl in sorted([list(d.items())[0] for d in value], 4 key=lambda x: x[1]): 5 print(ky + ":" + vl)

まだ走りません。printのところでTypeError: Can't convert 'int' object to str implicitly
が出ます。以下のようにするとやっと走ります。

python

1for key, value in sorted(results.items()): 2 print( key + "→") 3 for ky,vl in sorted([list(d.items())[0] for d in value], 4 key=lambda x: x[1]): 5 print(ky + ":" + str(vl)) 6""" # => 7A→ 8a:100 9b:200 10c:300 11B→ 12c:80 13a:400 14b:500 15C→ 16c:130 17a:340 18b:600 19D→ 20c:220 21a:250 22b:390 23"""

期待値と違う出力になるので、調整。

python

1for key, value in sorted(results.items()): 2 print( key + "→", end=" ") 3 for ky,vl in sorted([list(d.items())[0] for d in value], 4 key=lambda x: x[1]): 5 print(ky + ": " + str(vl), end=" ") 6 print("\n") 7""" # => 8A→ a: 100 b: 200 c: 300 9 10B→ c: 80 a: 400 b: 500 11 12C→ c: 130 a: 340 b: 600 13 14D→ c: 220 a: 250 b: 390 15 16"""

pythonの構文や、自分で作った変数の型をしっかり理解してプログラミングしてください。

投稿2018/05/10 04:19

hayataka2049

総合スコア30933

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

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

0

ベストアンサー

dfのデータ構造がごちゃごちゃしているので、それを少し整理できれば素直に書けます。

Python

1from operator import itemgetter 2 3df = { 4 "A": {"a": 100, "b": 200, "c": 300}, 5 "B": {"a": 400, "b": 500, "c": 80}, 6 "C": {"a": 340, "b": 600, "c": 130}, 7 "D": {"a": 250, "b": 390, "c": 220} 8} 9 10for key, value in sorted(df.items()): 11 print(f'{key}→', end=' ') 12 for k, v in sorted(value.items(), key=itemgetter(1)): 13 print(f'{k}:{v}', end=' ') 14 15 print()

実行結果 Wandbox

A→ a:100 b:200 c:300 B→ c:80 a:400 b:500 C→ c:130 a:340 b:600 D→ c:220 a:250 b:390

このアプローチの方が結果的には楽だと思うので、dfの作り方を工夫してください。

投稿2018/05/10 03:44

LouiS0616

総合スコア35658

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

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

k0908

2018/05/10 04:51

ありがとうございます。dfのデータ構造はどのようにコードを書けばLouis0616さんのように整理できますか?辞書を変形するコードを書いたのですが、うまくいかず・・・。
LouiS0616

2018/05/10 05:05

成形する方法でも良いですが、一番いいのは辞書を作る段階で扱いやすい形を意識することです。 dfはもともとどのように作ったのでしょう?
k0908

2018/05/10 05:13

{"a": 100}、{"b": 200}、{"c": 300}と配列の要素があって、それを arr=["A","B","C","D"] for i in range(len(arr)): fi = {} fi[i] = dic #{"a": 100}、{"b": 200}、{"c": 300}を入れる という形で作っています。
LouiS0616

2018/05/10 05:22

もともとの『{"a": 100}、{"b": 200}、{"c": 300}』は違う形で受け取れないのですか? 単一要素の辞書のリストは使いづらいですし、意味合い的にも不可解です。
k0908

2018/05/10 06:37

何とか自分でできました! ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問