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

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

ただいまの
回答率

88.81%

python 多次元リストにおける最大値の抽出

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 400

22Go

score 47

list = 
[('a', 'b', '97.4'), ('a', 'c', '69.3'), ('a', 'd', '100'), ('a', 'f', '95.9'), ('a', 'p', '68.9'), ('b', 'd', '64.7'), ('b', 'f', '191'), ('b', 'v', '213')]


このようなリストがあるときに、0番目の文字をキープしたまま2番目の最大値を抽出したいときはどうしたらいいでしょうか?

理想は

list_max = [('a', 'd', '100'),('b', 'v', '213')]

このように0番目の'a'の中で最も2番目の値が高いものをリスト化したいです。

再びエラーが発生してしまったので、編集追記させていただきます。

list = 
[('a', 'b', '100'), ('a', 'c', '69.3'), ('a', 'd', '100'), ('a', 'f', '95.9'), ('a', 'p', '68.9'), ('b', 'd', '64.7'), ('b', 'f', '191'), ('b', 'v', '213')]

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for x in lst:
...     d[x[0]].append(x)
... 
>>> result = [max(x, key=lambda x:float(x[2])) for x in d.values()]
>>> result
[('a', 'b', '100'),('b', 'v', '213')]

大量のデータを扱っていましたら、このように

('a', 'b', '100'), ('a', 'd', '100')


('a', 'b', '100')が優先でmax値として拾われたために('a', 'd', '100')のdを
スルーしてしました。。。

この場合はどのように抽出していったいいでしょうか?
質問ばかりで申し訳ありません。宜しくお願い致します。

なぜ値が重複してしまったときにどちらも抽出したいかというと、
2つのリストから共通するものを取り出したいためです。

from collections import defaultdict


hoge = [('a', 'b', '1'), ('a', 'c', '2'), ('a', 'd', '3'),('d', 'j', '10'),('d', 'k', '10'),
               ('b', 'x', '1'), ('b', 'x', '2'), ('b', 'x', '3'), ('c', 'v', '1'), ('c', 'v', '2')]

hoge2 = [('b', 'a', '1'), ('c', 'a', '2'), ('d', 'a', '4'),
               ('d', 'k', '5'),
               ('mm', 'b', '1'), ('nn', 'b', '2'), ('x', 'b', '5'), ('kk', 'c', '6'), ('v', 'c', '3')]

print("最大値")
from collections import defaultdict
d = defaultdict(list)
for x in hoge:
    d[x[0]].append(x)

result = [max(x, key=lambda x:float(x[2])) for x in d.values()]
print(result)

print("最大値")
a = defaultdict(list)
for x in hoge2:
    a[x[0]].append(x)

result2 = [max(x, key=lambda x:float(x[2])) for x in a.values()]
print(result2)

print("最大値でdict作成")
hoge_dict = {(k1, k2):v for k1, k2, v in result}
hoge2_dict = {(k4, k3):v for k3, k4, v in result2}



print("作ったdictから共通するものをだす")
ok = {k:hoge[k] for k in hoge_dict.keys() & hoge2_dict.keys()}

print(ok)


コード
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

itertools.groupbyで。

import itertools
import operator


src = [
    ('a', 'b', '97.4'), ('a', 'c', '69.3'), ('a', 'd', '100'), ('a', 'f', '95.9'), ('a', 'p', '68.9'),
    ('b', 'd', '64.7'), ('b', 'f', '191'), ('b', 'v', '213')
]

dst = []
for _, it in itertools.groupby(src, key=operator.itemgetter(0)):
    m = max(it, key=lambda e: float(e[-1]))
    dst.append(m)

print(dst)

実行結果 Wandbox

[('a', 'd', '100'), ('b', 'v', '213')]

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

0番目の要素ごとにまとめた後、抽出するといいと思われます。

pandasとかでも書けそうですが、標準の機能の範囲でやるなら下のような感じです。

>>> lst = [('a', 'b', '97.4'), ('a', 'c', '69.3'), ('a', 'd', '100'), ('a', 'f', '95.9'), ('a', 'p', '68.9'), ('b', 'd', '64.7'), ('b', 'f', '191'), ('b', 'v', '213')]
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for x in lst:
...     d[x[0]].append(x)
... 
>>> result = [max(x, key=lambda x:float(x[2])) for x in d.values()]
>>> result
[('b', 'v', '213'), ('a', 'd', '100')]

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/01 19:59

    そのデータは特に問題なさそうに思われます。エラーメッセージを全文示してください。

    キャンセル

  • 2019/06/01 20:00

    断定出来ませんが、listという変数名を使ってしまっているので、defaultdict(list)で失敗したような気がします。組み込み型・組み込み関数と被る変数名は避けるべきです。

    キャンセル

  • 2019/06/01 20:03

    仰る通りでした。変更したらできました。
    ありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る