|
| 1 | +:doc:`/index` |
| 2 | + |
| 3 | +Other Parameters |
| 4 | +================ |
| 5 | + |
| 6 | +.. _iterable_compare_func_label: |
| 7 | + |
| 8 | +Iterable Compare Func |
| 9 | +--------------------- |
| 10 | + |
| 11 | +New in DeepDiff 5.5.0 |
| 12 | + |
| 13 | +There are times that we want to guide DeepDiff as to what items to compare with other items. In such cases we can pass a `iterable_compare_func` that takes a function pointer to compare two items. It function takes two parameters and should return `True` if it is a match, `False` if it is not a match or raise `CannotCompare` if it is unable to compare the two. |
| 14 | + |
| 15 | + |
| 16 | +For example take the following objects: |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | +Now let's define a compare_func that takes 3 parameters: x, y and level. |
| 21 | + |
| 22 | + >>> from deepdiff import DeepDiff |
| 23 | + >>> from deepdiff.helper import CannotCompare |
| 24 | + >>> |
| 25 | + >>> t1 = [ |
| 26 | + ... { |
| 27 | + ... 'id': 1, |
| 28 | + ... 'value': [1] |
| 29 | + ... }, |
| 30 | + ... { |
| 31 | + ... 'id': 2, |
| 32 | + ... 'value': [7, 8, 1] |
| 33 | + ... }, |
| 34 | + ... { |
| 35 | + ... 'id': 3, |
| 36 | + ... 'value': [7, 8], |
| 37 | + ... }, |
| 38 | + ... ] |
| 39 | + >>> |
| 40 | + >>> t2 = [ |
| 41 | + ... { |
| 42 | + ... 'id': 2, |
| 43 | + ... 'value': [7, 8] |
| 44 | + ... }, |
| 45 | + ... { |
| 46 | + ... 'id': 3, |
| 47 | + ... 'value': [7, 8, 1], |
| 48 | + ... }, |
| 49 | + ... { |
| 50 | + ... 'id': 1, |
| 51 | + ... 'value': [1] |
| 52 | + ... }, |
| 53 | + ... ] |
| 54 | + >>> |
| 55 | + >>> DeepDiff(t1, t2) |
| 56 | + {'values_changed': {"root[0]['id']": {'new_value': 2, 'old_value': 1}, "root[0]['value'][0]": {'new_value': 7, 'old_value': 1}, "root[1]['id']": {'new_value': 3, 'old_value': 2}, "root[2]['id']": {'new_value': 1, 'old_value': 3}, "root[2]['value'][0]": {'new_value': 1, 'old_value': 7}}, 'iterable_item_added': {"root[0]['value'][1]": 8}, 'iterable_item_removed': {"root[2]['value'][1]": 8}} |
| 57 | + |
| 58 | +As you can see the results are different. Now items with the same ids are compared with each other. |
| 59 | + |
| 60 | + >>> def compare_func(x, y, level=None): |
| 61 | + ... try: |
| 62 | + ... return x['id'] == y['id'] |
| 63 | + ... except Exception: |
| 64 | + ... raise CannotCompare() from None |
| 65 | + ... |
| 66 | + >>> DeepDiff(t1, t2, iterable_compare_func=compare_func) |
| 67 | + {'iterable_item_added': {"root[2]['value'][2]": 1}, 'iterable_item_removed': {"root[1]['value'][2]": 1}} |
| 68 | + |
| 69 | +If we set the verbose_level=2, we can see more details. |
| 70 | + |
| 71 | + >>> DeepDiff(t1, t2, iterable_compare_func=compare_func, verbose_level=2) |
| 72 | + {'iterable_item_added': {"root[2]['value'][2]": 1}, 'iterable_item_removed': {"root[1]['value'][2]": 1}, 'iterable_item_moved': {'root[0]': {'new_path': 'root[2]', 'value': {'id': 1, 'value': [1]}}, 'root[1]': {'new_path': 'root[0]', 'value': {'id': 2, 'value': [7, 8]}}, 'root[2]': {'new_path': 'root[1]', 'value': {'id': 3, 'value': [7, 8, 1]}}}} |
| 73 | + |
| 74 | + |
| 75 | +We can also use the level parameter. |
| 76 | + |
| 77 | +.. note:: |
| 78 | + |
| 79 | + The level parameter of the iterable_compare_func is only used when ignore_order=False which is the default. |
| 80 | + |
| 81 | + |
| 82 | +Back to :doc:`/index` |
0 commit comments