LoginSignup
5
0

More than 1 year has passed since last update.

【Python】並び順を無視してリストを比較するテスト(DeepDiff)

Posted at

やりたいこと

>>> dict_in_list1
[
 	{'name': 'Reimu', 'spells': ['Musouhuin', 'niju-kekkai']},
 	{'name': 'Marisa', 'spells': ['non-directional laser', 'star-dust reverie']},
    {'name': 'Alice', 'spells': ['hourai-doll', 'shanghai-doll']}
]

>>> dict_in_list2
[
	{'name': 'Marisa', 'spells': ['star-dust reverie', 'non-directional laser']},
 	{'name': 'Reimu', 'spells': ['Musouhuin', 'niju-kekkai']},
 	{'name': 'Alice', 'spells': ['hourai-doll', 'shanghai-doll']}
]

  1. dictを要素として持つlistがあり、「同じデータ」かを比べたい.
    • ただし並び順は異なっていても良いとする。
  2. dictのあるvalue(下例ではspell)もlistとなっている。
    • こちらの要素も並び順は異なっていても良いとする。

2の要件は、name: Marisa 要素のspells部分のことです。順番が逆になってますが、これは「同じデータ」として扱いたいです.

'spells': ['non-directional laser', 'star-dust reverie']
'spells': ['star-dust reverie', 'non-directional laser']

解決方法

DeepDiffを使うと、以下のようにして同じデータであるかを比較できる.

$ pip install deepdiff

pytest

assert not DeepDiff(dict_in_list1, dict_in_list2, ignore_order=True)

unittest

self.assertEqual(DeepDiff(dict_in_list1, dict_in_list2, ignore_order=True), {})

その他の方法

もし、要素であるdictのvalueがstrなどだった場合は、sortedで並び替える(おすすめ) or assertCountEqualメソッドを使うのもアリだと思います。

以下のような単純な例だと、key引数を指定したsortを使う方が明瞭なのでおすすめです。

names1 = [
    {"name": "Reimu"},
    {"name": "Marisa"},
    {"name": "Alice"},
]
names2 = [
    {"name": "Alice"},
    {"name": "Reimu"},
    {"name": "Marisa"},
]
>>> from unittest import TestCase
>>> case = TestCase()
>>> case.assertCountEqual(names1, names2)  # OK!!

assertCountEqualはその名前から↑のような比較ができるようには見えないですが、問題なく機能します。

余談

assertCountEqualメソッドの本来の使い方は、おそらく以下のようなケース(要素ごとの数え上げ)だと思います.(多分)

>>> fruits1 = ["りんご", "みかん", "みかん", "りんご", "りんご"]
>>> fruits2 = ["りんご", "みかん", "みかん", "りんご", "みかん"]
>>> case.assertCountEqual(fruits1, fruits2)

AssertionError: Element counts were not equal:
First has 3, Second has 2:  'りんご'
First has 2, Second has 3:  'みかん'

メッセージもわかりやすいですね。

5
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0