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

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

ただいまの
回答率

87.61%

複数の値が格納されたリスト型をvalueとした辞書から、valueが一致するkeyだけを取り出してリストに格納したい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 3,107

score 18

前提・実現したいこと

現在私は、複数の値が格納されたリスト型をvalueとした3つの辞書を用いて、「もしvalueとしたリスト内に同じ値が3つの辞書全てにあった際に、そのvalueのkeyを3組とした新たなリストを生成する」プログラムを構築することを目的としています。
例として、辞書が

1_dict = {A:[0,1,2]}
2_dict = {C:[0,2,3],D:[1,2]}
3_dict = {E:[2,3],F:[0],G:[1]}


である場合は

[[A,C,F](valueの0が共通),[A,D,G](valueの1が共通),[A,C,E](valueの2が共通),[A,D,E](valueの2が共通)]


というリストを(valueの~が共通)という部分を除いて出力させたいと考えています。

そのための処理として、「辞書のkeyとvalueをそれぞれ別のリストに格納した上で、入れ子構造のリストになったvalueのリストを回すことで数値が一致しているか確認した上で、key要素を格納したリストと照合させてkey要素を抽出、出力用のリストに入れる」という処理を実現させたいと考えています。

発生している問題・エラーメッセージ

しかし、value要素を格納したリストを回そうとした所、以下のエラーメッセージが発生してしまいました。

   for x1,x2,x3 in val1,val2,val3:
ValueError: too many values to unpack (expected 3)

該当のソースコード

#coding:utf-8
import re
import pandas as pd
#import numpy as np#数値計算を容易にする
from collections import defaultdict#辞書型で一つのkeyに複数のvalueをappend処理できるようにする
from itertools import zip_longest#zip_longestは最も長い要素に合わせて要素をまとめる処理

1_dict = {A:[0,2,4,6],B:[0,1,2,3,7]}
2_dict = {C:[1,2,3,5],D:[1,2,5,6]}
3_dict = {E:[2,3,6,7],F:[0,2,3,6],G:[1,4,6]}

key1,key2,key3 = [],[],[]#辞書のkeyのみを格納するリスト
val1,val2,val3 = [],[],[]#辞書のvalueのみを格納するリスト
res = []#出力用のリスト

for 1_key,1_value in 1_dict.items():
    key1.append(1_key)#辞書のkey部分のみを格納
    val1.append(1_value)#辞書のvalue部分のみを格納

for 2_key,2_value in 2_dict.items():
    key2.append(2_key)#辞書のkey部分のみを格納
    val2.append(2_value)#辞書のvalue部分のみを格納

for 3_key,3_value in 3_dict.items():
    key3.append(3_key)#辞書のkey部分のみを格納
    val3.append(3_value)#辞書のvalue部分のみを格納

for x1,x2,x3 in val1,val2,val3:#
    for y1,y2,y3 in val1[x1][-1],val2[x2][-1],val3[x3][-1]:
        if (val_hi[x1][y1] - val_ha[x2][y2]) ** 2 == 0 and (val_hi[x1][y1] - val_t[x3][y3]) ** 2 == 0:
            res.append(key1[x1],key2[x2],key3[x3])


理想の出力

res = [[B,C,G],[B,D,G],[A,C,E],[A,C,F],[A,D,E],[A,D,F],[B,C,E],[B,C,F],[B,D,E],[B,D,F],[B,C,E].[B,C,F],[A,D,E],[A,D,F],[A,D,F],[A,D,G]]

試したこと

for x1,x2,x3 in key1,key2,key3:
    for y1,y2,y3 in val1[x1][-1],val2[x2][-1],val3[x3][-1]:


の部分をいくらかいじっていましたが、どうにもなりませんでした。

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

Pythonのバージョンは3.6.5です。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • gran-1123

    2019/02/21 15:46

    先に出現するkey要素を優先的に取り出すルールで三つ組を作成しています。
    また、DもCが取り出された後に取り出します。

    キャンセル

  • can110

    2019/02/21 15:55

    一般的に辞書はキーの並びは順不同なのですが
    とにかく先に出現したものを優先して取り出したいということでよいでしょうか?

    キャンセル

  • gran-1123

    2019/02/21 15:56

    重複して取り出されるようなことがない限りは問題ありません。

    キャンセル

回答 2

checkベストアンサー

0

追記

提示コードは実行できないため確認していませんが、以下のような結果を得たいということでしょうか。

# 出現する値を(昇順に)取得したリストを返す
def get_values(dlst):
    values = set()
    for d in dlst:
        for v in d.values():
            values |= set(v)
    return sorted(list(values))


# キーと値を逆にした辞書のリストを返す
def get_reveased_kv(dlst):
    revs = []
    for d in dlst:
        rev = {}
        for key,lst in d.items():
            for v in lst:
                if not v in rev:
                    rev[v] = []
                rev[v].append(key)
        revs.append(rev)
    return revs


d1 = {'A':[0,1,2]}
d2 = {'C':[0,2,3],'D':[1,2]}
d3 = {'E':[2,3],'F':[0],'G':[1]}

dlst = [d1,d2,d3]

values = get_values(dlst)
print(values) # [0, 1, 2, 3]

revs = get_reveased_kv(dlst)
print(revs)# [{0: ['A'], 1: ['A'], 2: ['A']}, {0: ['C'], 2: ['C', 'D'], 3: ['C'], 1: ['D']}, {2: ['E'], 3: ['E'], 0: ['F'], 1: ['G']}]

import itertools
ret = []
for val in values: # 値毎に
    lsts = []
    for d in revs: # 各辞書から値を含むキー(リスト)を取得
        if val in d:
            lsts.append(d[val])
    if len(lsts) == len(revs): # すべての辞書からキーが見つかった
        for p in itertools.product(*lsts): # 全組み合わせ(直積)を列挙
            ret.append(p)

print(ret) # [('A', 'C', 'F'), ('A', 'D', 'G'), ('A', 'C', 'E'), ('A', 'D', 'E')]

以前の回答

d1 = {'A':[0,1,2]}
d2 = {'C':[0,2,3],'D':[1,2]}
d3 = {'E':[2,3],'F':[0],'G':[1]}

dlst = [d1,d2,d3]

# 出現する値を(昇順に)取得
values = set()
for d in dlst:
    for v in d.values():
        values |= set(v)
values = sorted(list(values))
#print(values) # [0, 1, 2, 3]

# 結果を取得
ret = []
for val in values:
    l = []
    for d in dlst:
        for k,v in d.items():
            if val in v:
                l.append(k)
                break # 先に出現したもののみ
    ret.append(l)
print(ret) # [['A', 'C', 'F'], ['A', 'D', 'G'], ['A', 'C', 'E'], ['C', 'E']]

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

複数のイテラブルを並行して巡回したい場合は、zipしてください。

>>> lst1 = [1, 2, 3, 4, 5]
>>> lst2 = [6, 7, 8, 9, 0]
>>>
>>> for e1, e2 in lst1, lst2:
...     print(e1, e2)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
>>>
>>> for e1, e2 in zip(lst1, lst2):
...     print(e1, e2)
...
1 6
2 7
3 8
4 9
5 0

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/21 15:27

    回答をを元に、要素が欠落しないようにzip_longestで回した所、
    for y1,y2,y3 in zip_longest(val1[x1],val2[x2],val3[x3]):
    TypeError: list indices must be integers or slices, not list
    このようなエラーが発生しました。
    入れ子構造のリストを回す過程でどのような問題が発生したと考えられますか?

    なお、val1[x1]~の中身は、リストであると考えています。

    キャンセル

  • 2019/02/21 15:34

    x1, x2, x3 の巡回の際にもzipしないと。

    > なお、val1[x1]~の中身は、リストであると考えています。
    実際に出力して確かめてみるのが早いです。

    キャンセル

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

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

関連した質問

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

  • トップ
  • Python 3.xに関する質問
  • 複数の値が格納されたリスト型をvalueとした辞書から、valueが一致するkeyだけを取り出してリストに格納したい