Skip to content

Commit

Permalink
Merge pull request #12 from spencer-hanson/flatten-wip
Browse files Browse the repository at this point in the history
SimpleFlatten ver 0.3.3
  • Loading branch information
spencer-hanson authored Jun 9, 2023
2 parents b492a8d + b7e81b2 commit 926ae9d
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# CHANGELOG

## 0.3.3 - 2023-6-9
* Added a simple dict flattener utility class

## 0.3.2 - 2021-5-31
## 0.3.1 - 2021-5-31
* Fixed tests and published
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
dict-plus v0.0.4
dict-plus
Documentation: https://dict-plus.readthedocs.io/en/latest/

Empty file added dict_plus/utils/__init__.py
Empty file.
67 changes: 67 additions & 0 deletions dict_plus/utils/simpleflatten.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import math


class SimpleFlattener(object):
"""
Utility class to flatten simple dictionaries into a top-level only dict
e.g.
{"a": {"a1": 1, "a2": 2}, "b": {"b1": 3, "b2": 4}}
would flatten to
{"a_a1": 1, "a_a2": 2, "b_b1": 3, "b_b2": 4}
Not meant to be a general dictionary flattener TODO?
"""

class _SimpleListType(object):
"""
Helper class to distinguish a 'Simple List' a list of simple typed data
"""
def __init__(self, val):
self.val = val

def __init__(self, simple_types=[], maxdepth=math.inf):
"""
simple_types is a list of types that should be treated as simple, base cases
maxdepth is the maximum depth within the data to traverse, defaults to no maximum
"""
self.simple_types = {str, bytes, int, float, bool, tuple}
self.max_depth = maxdepth
for s in simple_types:
self.simple_types.add(s)

def is_simplelist(self, val):
"""
Check if a list is only of simple_types and also not mixed types
"""
if isinstance(val, list):
list_types = set()
for element in val:
list_types.add(type(element))
if len(list_types) == 1: # Only one type of element in the list
if list_types.pop() in self.simple_types:
return True
return False # Multiple types of data within the list, or data is not simple
else:
return False

def flatten(self, data, current_depth=0, key_prefix=""):
if key_prefix:
key_prefix = f"{key_prefix}_"

if current_depth > self.max_depth:
return {key_prefix: data}

if isinstance(data, dict):
newdict = {}
for key, val in data.items():
new_keyprefix = f"{key_prefix}{key}"
if type(val) in self.simple_types:
newdict[new_keyprefix] = val
else:
newdict.update(self.flatten(val, current_depth=current_depth+1, key_prefix=new_keyprefix))
return newdict
elif isinstance(data, list):
if self.is_simplelist(data):
return {key_prefix: data}

raise ValueError(f"SimpleFlatten cannot flatten data: '{data}'")
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import setup
import json

VERSION = "0.3.2"
VERSION = "0.3.3"


def check_version_info():
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "0.3.2"
"version": "0.3.3"
}

0 comments on commit 926ae9d

Please sign in to comment.