2017-12-20 21 views
2

Python 3.6で辞書の2つのリストを並べ替えて比較する方法を探しています。私は最終的にlist_dict_alist_dict_b==と比較し、Trueと評価したいだけです。ここでDicts Pythonの並べ替えと比較

は、データがどのように見えるかです:

list_dict_a = [ 
{'expiration_date': None, 'identifier_country': None, 'identifier_number': 'Male', 'identifier_type': 'Gender', 'issue_date': None}, 
{'expiration_date': None, 'identifier_country': 'VE', 'identifier_number': '1234567', 'identifier_type': 'Foo No.', 'issue_date': None}] 

list_dict_b = [ 
{'identifier_country': 'VE', 'expiration_date': None, 'identifier_type': 'Foo No.', 'issue_date': None, 'identifier_number': '1234567'}, 
{'identifier_country': None, 'expiration_date': None, 'identifier_type': 'Gender', 'issue_date': None, 'identifier_number': 'Male'}] 

データは同じですが、それは(私が最初の順序を任意のコントロールを持っていけない)異なる順序で提供されます。

私のようなそれらを比較しようとすると、このような何かをやったときに、私は偽の値を取得する: print("does this match anything",list_dict_a == list_dict_b)

を行うのは、これがさえ可能ですか?

+0

https://stackoverflow.com/questions/9845369/comparing-2-lists-consisting-of-dictionaries-with-unique-keys-in-python –

答えて

2

あなたがそれらを比較する前に両方のリストをソートし、ソート結果を比較することができます

>>> list_dict_a = [ 
     {'expiration_date': None, 'identifier_country': None, 'identifier_number': 'Male', 'identifier_type': 'Gender', 'issue_date': None}, 
     {'expiration_date': None, 'identifier_country': 'VE', 'identifier_number': '1234567', 'identifier_type': 'Foo No.', 'issue_date': None}] 

>>> list_dict_b = [ 
     {'identifier_country': 'VE', 'expiration_date': None, 'identifier_type': 'Foo No.', 'issue_date': None, 'identifier_number': '1234567'}, 
     {'identifier_country': None, 'expiration_date': None, 'identifier_type': 'Gender', 'issue_date': None, 'identifier_number': 'Male'}] 

>>> list_dict_a == list_dict_b 
False 
>>> def key_func(d): 
     items = ((k, v if v is not None else '') for k, v in d.items()) 
     return sorted(items) 
>>> sorted(list_dict_a, key=key_func) == sorted(list_dict_b, key=key_func) 
True 

、その後は問題ではありません各リスト内のdictsの順。

dictsは順序付け可能ではないので、key関数を渡す必要があります。したがって、dictオブジェクトの各ペアにどのキーを使用するかをソート関数に指示する必要があります。各辞書のキーは、単に(キー、値)のペアのソートされたリストです。

>>> dict_a0 = list_dict_a[0] 
>>> key_func(dict_a0) 
[('expiration_date', ''), ('identifier_country', ''), ('identifier_number', 'Male'), ('identifier_type', 'Gender'), ('issue_date', '')] 

脚注

のために(キー、値)ペアのリストのための他のdicts'リストと同等であると次のよう

キー機能は、各辞書のためのキーを計算します、Noneの値を空の文字列に変換する必要がありました。これにより、None値を他の非None値と比較できるようになります。

上記のソリューションの根底にある仮定は、ケースのすべての辞書値が文字列かNoneであり、 "空の"値が一貫してNone(空の文字列などではない)として表されるということです。これが当てはまらない場合には、結果として得られるリストが常にデータ内で予想される任意のdict値に対して互いに匹敵することを保証するために、key_func()を調整する必要があります。

また、大規模な辞書の場合、このキー機能は、キーペアの比較が遅すぎるため、理想的ではない可能性があります。したがって、代わりに各dict(しかし、同等のものを比較するdictsのための同じハッシュ)の一意のハッシュ値を計算する方が良いでしょう。

+0

私が 'foo1 = sorted(list_dict_a)'と ' foo2 = sorted(list_dict_b) 'と比較しようとしました。' TypeError:unorderable types:dict()

+0

ああ...すみません、Python 3はそれを逃しました。答えを調整します。 – plamut

+0

そして、キー機能のバグを修正してください:) – plamut

0

あなたもlist_dict_aの各辞書はlist_dict_b

all([dict_a in list_dict_b for dict_a in list_dict_a]) 

Out[218]: True 
+1

これはO(n^2)の解決策...またはO(a * b)であることにご注意ください。ここで、aとbはリストaとbの長さです。この違いは、より大きなデータセットではかなりのものになります。 – plamut

0

にある場合は、この試すことができますチェックすることができます:あなたがわからない場合

True 

list_dict_a = [ 
{'expiration_date': None, 'identifier_country': None, 'identifier_number': 'Male', 'identifier_type': 'Gender', 'issue_date': None}, 
{'expiration_date': None, 'identifier_country': 'VE', 'identifier_number': '1234567', 'identifier_type': 'Foo No.', 'issue_date': None}] 

list_dict_b = [ 
{'identifier_country': 'VE', 'expiration_date': None, 'identifier_type': 'Foo No.', 'issue_date': None, 'identifier_number': '1234567'}, 
{'identifier_country': None, 'expiration_date': None, 'identifier_type': 'Gender', 'issue_date': None, 'identifier_number': 'Male'}] 
new_list = sorted(list_dict_a, key=lambda x:x['identifier_country'] is not None, reverse=True) 
print(new_list == list_dict_b) 

出力をキーはもともと、あなたはこれを試すことができます:

new_list = sorted(list_dict_a, key=lambda x:x.get('identifier_country', None) is not None, reverse=True) 
+0

もし私が鍵を知らなかったら、代わりに 'key = lambda x:x [0]'をすることができますか? –

+0

@unseen_damageいいえ、ラムダ関数の範囲では、 'x'は辞書であり、' x [0] 'は' KeyError'を送出します。ただし、 'dict.get'を使用してデフォルトのアライメントを提供することはできます。私の最近の編集を見てください。 – Ajax1234

関連する問題