lkj 0.1.40__py3-none-any.whl → 0.1.42__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
lkj/__init__.py CHANGED
@@ -13,6 +13,7 @@ from lkj.dicts import (
13
13
  inclusive_subdict, # new dictionary with only the keys in `include`
14
14
  exclusive_subdict, # new dictionary with only the keys not in `exclude`.
15
15
  merge_dicts, # Merge multiple dictionaries recursively
16
+ compare_field_values, # Compare two dictionaries' values
16
17
  )
17
18
  from lkj.filesys import get_app_data_dir, get_watermarked_dir, enable_sourcing_from_file
18
19
  from lkj.strings import (
lkj/dicts.py CHANGED
@@ -224,7 +224,11 @@ Comparison = Any
224
224
  Comparator = Callable[[dict, dict], Comparison]
225
225
 
226
226
 
227
- def compare_dicts(
227
+ def _common_keys_list(dict1, dict2):
228
+ return [k for k in dict1.keys() if k in dict2.keys()]
229
+
230
+
231
+ def compare_field_values(
228
232
  dict1,
229
233
  dict2,
230
234
  *,
@@ -232,16 +236,17 @@ def compare_dicts(
232
236
  default_comparator: Comparator = operator.eq,
233
237
  aggregator: Callable[
234
238
  [Dict[KT, Comparison]], Any
235
- ] = lambda d: d, # lambda d: np.mean(list(d.values()))
239
+ ] = lambda d: d, # lambda d: np.mean(list(d.values())),
240
+ get_comparison_fields: Callable[[dict], Iterable[KT]] = _common_keys_list,
236
241
  ):
237
242
  """
238
- Compare two dictionaries field by field using specified comparators or a default comparator.
243
+ Compare two dictionaries' values field by field
239
244
 
240
245
  :param dict1: The first dictionary.
241
246
  :param dict2: The second dictionary.
242
247
  :param field_comparators: A dictionary where keys are field names and values are comparator functions.
243
248
  :param default_comparator: A default comparator function to use if no specific comparator is provided for a field.
244
- :param aggregator: A function to aggregate the comparison results into a final score.
249
+ :param aggregator: A function to aggregate the comparison results into a final comparison object.
245
250
  :return: A final score based on the comparison results.
246
251
 
247
252
  >>> dict1 = {"color": "brown", "animal": "dog"}
@@ -251,22 +256,22 @@ def compare_dicts(
251
256
  ... "color": lambda x, y: 1 if x == y else 0,
252
257
  ... "animal": lambda x, y: 1 if len(x) == len(y) else 0
253
258
  ... }
254
- >>> compare_dicts(dict1, dict2, field_comparators=field_comparators)
259
+ >>> compare_field_values(dict1, dict2, field_comparators=field_comparators)
255
260
  {'color': 1, 'animal': 1}
256
- >>> compare_dicts(dict1, dict3, field_comparators=field_comparators)
261
+ >>> compare_field_values(dict1, dict3, field_comparators=field_comparators)
257
262
  {'color': 1, 'animal': 0}
258
263
  >>> import functools, statistics
259
264
  >>> aggregator = lambda d: statistics.mean(d.values())
260
- >>> my_compare_dicts = functools.partial(
261
- ... compare_dicts, field_comparators=field_comparators, aggregator=aggregator
265
+ >>> mean_of_values = functools.partial(
266
+ ... compare_field_values, field_comparators=field_comparators, aggregator=aggregator
262
267
  ... )
263
- >>> my_compare_dicts(dict1, dict2)
268
+ >>> mean_of_values(dict1, dict2)
264
269
  1
265
- >>> my_compare_dicts(dict1, dict3)
270
+ >>> mean_of_values(dict1, dict3)
266
271
  0.5
267
272
 
268
273
  """
269
- common_keys = [k for k in dict1.keys() if k in dict2.keys()]
274
+ common_keys = get_comparison_fields(dict1, dict2)
270
275
 
271
276
  comparisons = {}
272
277
  for key in common_keys:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lkj
3
- Version: 0.1.40
3
+ Version: 0.1.42
4
4
  Summary: A dump of homeless useful utils
5
5
  Home-page: https://github.com/thorwhalen/lkj
6
6
  Author: Thor Whalen
@@ -1,6 +1,6 @@
1
- lkj/__init__.py,sha256=YEPCVj-0EJOfpapgX3Vw07399w13OkCm39KCmCi5AQg,6806
1
+ lkj/__init__.py,sha256=Vceal0uY2jW1y0sQHOk1WHXc9aTAEXXOJ9vgyOmnrNk,6868
2
2
  lkj/chunking.py,sha256=RpNdx5jEuO4mFg2qoTkD47iL35neBneuZ5xgQ_cBkiM,3755
3
- lkj/dicts.py,sha256=nfciX_h7tplR3cbaDYcQvucb7UWzv8vmvp2NDEiQm-4,10227
3
+ lkj/dicts.py,sha256=z2o7njvLNJkh1ZgSH-SLtz13SdW_YfUsTA1yTY-kVLE,10382
4
4
  lkj/filesys.py,sha256=NbWDuc848h8O42gwX7d9yNJkrWBgzSFnkoEdSRgvBAg,8883
5
5
  lkj/funcs.py,sha256=LXJlj3gMMsbD0t2gn2NZZ6mOqmW5bxM-94uGoYgrhzI,8930
6
6
  lkj/importing.py,sha256=_BFBmdaKCBnk5broltWDeAPeEKG1dEkS8DhIdv6UhSI,3809
@@ -8,8 +8,8 @@ lkj/iterables.py,sha256=9jeO36w-IGiZryge7JKgXZOGZAgehUvhwKV3nHPcZWk,2801
8
8
  lkj/loggers.py,sha256=ImmBdacz89Lvb3dg_xI5jOct_44rSRv0hNI_CVehy60,13706
9
9
  lkj/misc.py,sha256=IZf05tkl0cgiMgBwCMH5cLSC59fRXwnemPRo8G0OxQg,1436
10
10
  lkj/strings.py,sha256=3YjlxOWUfzWqwu51uq_pv9XZReLqRFvziGtRsdzEtw8,24662
11
- lkj-0.1.40.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
12
- lkj-0.1.40.dist-info/METADATA,sha256=MQn5N_4SfIm7fUZl9zCTtuSTz94PYPenG7EZd8juq14,4684
13
- lkj-0.1.40.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
14
- lkj-0.1.40.dist-info/top_level.txt,sha256=3DZOUwYmyurJFBXQCvCmEIVm8z2b42O5Sx3RDQyePfg,4
15
- lkj-0.1.40.dist-info/RECORD,,
11
+ lkj-0.1.42.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
12
+ lkj-0.1.42.dist-info/METADATA,sha256=vvlxvyZs9Nz9Uk_9l5ZNToXTrViVa4WOKVH5YkDzsHU,4684
13
+ lkj-0.1.42.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
14
+ lkj-0.1.42.dist-info/top_level.txt,sha256=3DZOUwYmyurJFBXQCvCmEIVm8z2b42O5Sx3RDQyePfg,4
15
+ lkj-0.1.42.dist-info/RECORD,,
File without changes
File without changes