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

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

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

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

Q&A

解決済

2回答

1340閲覧

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

gran-1123

総合スコア18

Python 3.x

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

0グッド

0クリップ

投稿2019/02/21 06:08

前提・実現したいこと

現在私は、複数の値が格納されたリスト型を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)

該当のソースコード

Python3

1#coding:utf-8 2import re 3import pandas as pd 4#import numpy as np#数値計算を容易にする 5from collections import defaultdict#辞書型で一つのkeyに複数のvalueをappend処理できるようにする 6from itertools import zip_longest#zip_longestは最も長い要素に合わせて要素をまとめる処理 7 81_dict = {A:[0,2,4,6],B:[0,1,2,3,7]} 92_dict = {C:[1,2,3,5],D:[1,2,5,6]} 103_dict = {E:[2,3,6,7],F:[0,2,3,6],G:[1,4,6]} 11 12key1,key2,key3 = [],[],[]#辞書のkeyのみを格納するリスト 13val1,val2,val3 = [],[],[]#辞書のvalueのみを格納するリスト 14res = []#出力用のリスト 15 16for 1_key,1_value in 1_dict.items(): 17 key1.append(1_key)#辞書のkey部分のみを格納 18 val1.append(1_value)#辞書のvalue部分のみを格納 19 20for 2_key,2_value in 2_dict.items(): 21 key2.append(2_key)#辞書のkey部分のみを格納 22 val2.append(2_value)#辞書のvalue部分のみを格納 23 24for 3_key,3_value in 3_dict.items(): 25 key3.append(3_key)#辞書のkey部分のみを格納 26 val3.append(3_value)#辞書のvalue部分のみを格納 27 28for x1,x2,x3 in val1,val2,val3:# 29 for y1,y2,y3 in val1[x1][-1],val2[x2][-1],val3[x3][-1]: 30 if (val_hi[x1][y1] - val_ha[x2][y2]) ** 2 == 0 and (val_hi[x1][y1] - val_t[x3][y3]) ** 2 == 0: 31 res.append(key1[x1],key2[x2],key3[x3]) 32

理想の出力

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です。

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

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

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

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

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

can110

2019/02/21 06:27

valueの2が共通なのはA,C,D,Eでなはいでしょうか?
gran-1123

2019/02/21 06:31

一つのdictから一つのkeyのみを抽出して三つ組を構築することを目的としているので、 [A,C,E],[A,C,F],[A,D,E],[A,D,F] の四つの三つ組を出力することが目的になっています。 そのため、問題上記の例は意図的なものです。
can110

2019/02/21 06:39

valueの2が共通なkeyを2_dictから取り出す場合、C,Dともに2を含みますが DではなくCを取り出すルールは何でしょうか?
gran-1123

2019/02/21 06:46

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

2019/02/21 06:55

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

2019/02/21 06:56

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

回答2

0

ベストアンサー

追記

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

Python

1# 出現する値を(昇順に)取得したリストを返す 2def get_values(dlst): 3 values = set() 4 for d in dlst: 5 for v in d.values(): 6 values |= set(v) 7 return sorted(list(values)) 8 9 10# キーと値を逆にした辞書のリストを返す 11def get_reveased_kv(dlst): 12 revs = [] 13 for d in dlst: 14 rev = {} 15 for key,lst in d.items(): 16 for v in lst: 17 if not v in rev: 18 rev[v] = [] 19 rev[v].append(key) 20 revs.append(rev) 21 return revs 22 23 24d1 = {'A':[0,1,2]} 25d2 = {'C':[0,2,3],'D':[1,2]} 26d3 = {'E':[2,3],'F':[0],'G':[1]} 27 28dlst = [d1,d2,d3] 29 30values = get_values(dlst) 31print(values) # [0, 1, 2, 3] 32 33revs = get_reveased_kv(dlst) 34print(revs)# [{0: ['A'], 1: ['A'], 2: ['A']}, {0: ['C'], 2: ['C', 'D'], 3: ['C'], 1: ['D']}, {2: ['E'], 3: ['E'], 0: ['F'], 1: ['G']}] 35 36import itertools 37ret = [] 38for val in values: # 値毎に 39 lsts = [] 40 for d in revs: # 各辞書から値を含むキー(リスト)を取得 41 if val in d: 42 lsts.append(d[val]) 43 if len(lsts) == len(revs): # すべての辞書からキーが見つかった 44 for p in itertools.product(*lsts): # 全組み合わせ(直積)を列挙 45 ret.append(p) 46 47print(ret) # [('A', 'C', 'F'), ('A', 'D', 'G'), ('A', 'C', 'E'), ('A', 'D', 'E')]

以前の回答

Python

1d1 = {'A':[0,1,2]} 2d2 = {'C':[0,2,3],'D':[1,2]} 3d3 = {'E':[2,3],'F':[0],'G':[1]} 4 5dlst = [d1,d2,d3] 6 7# 出現する値を(昇順に)取得 8values = set() 9for d in dlst: 10 for v in d.values(): 11 values |= set(v) 12values = sorted(list(values)) 13#print(values) # [0, 1, 2, 3] 14 15# 結果を取得 16ret = [] 17for val in values: 18 l = [] 19 for d in dlst: 20 for k,v in d.items(): 21 if val in v: 22 l.append(k) 23 break # 先に出現したもののみ 24 ret.append(l) 25print(ret) # [['A', 'C', 'F'], ['A', 'D', 'G'], ['A', 'C', 'E'], ['C', 'E']]

投稿2019/02/21 06:58

編集2019/02/21 07:49
can110

総合スコア38262

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

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

0

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

Python

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

投稿2019/02/21 06:16

LouiS0616

総合スコア35660

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

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

gran-1123

2019/02/21 06: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]~の中身は、リストであると考えています。
LouiS0616

2019/02/21 06:34

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問