Transform all the nodes of a tree. Args: tree: iterable or not. If iterable, its elements (child) can also be iterable or not. fn: function to apply to each leaves. iterable_type: type use to construct the resulting tree for unknown iterable, typically `list` or `tuple`.
(tree, fn, iterable_type=tuple)
| 131 | |
| 132 | |
| 133 | def transform_tree(tree, fn, iterable_type=tuple): |
| 134 | """Transform all the nodes of a tree. |
| 135 | |
| 136 | Args: |
| 137 | tree: iterable or not. If iterable, its elements (child) can also be |
| 138 | iterable or not. |
| 139 | fn: function to apply to each leaves. |
| 140 | iterable_type: type use to construct the resulting tree for unknown |
| 141 | iterable, typically `list` or `tuple`. |
| 142 | Returns: |
| 143 | A tree whose leaves has been transformed by `fn`. |
| 144 | The hierarchy of the output tree mimics the one of the input tree. |
| 145 | """ |
| 146 | if is_iterable(tree): |
| 147 | if isinstance(tree, dict): |
| 148 | res = tree.__new__(type(tree)) |
| 149 | res.__init__( |
| 150 | (k, transform_tree(child, fn)) for k, child in iteritems(tree)) |
| 151 | return res |
| 152 | elif isinstance(tree, tuple): |
| 153 | # NamedTuple? |
| 154 | if hasattr(tree, "_asdict"): |
| 155 | res = tree.__new__(type(tree), **transform_tree(tree._asdict(), fn)) |
| 156 | else: |
| 157 | res = tree.__new__(type(tree), |
| 158 | (transform_tree(child, fn) for child in tree)) |
| 159 | return res |
| 160 | elif isinstance(tree, collections_abc.Sequence): |
| 161 | res = tree.__new__(type(tree)) |
| 162 | res.__init__(transform_tree(child, fn) for child in tree) |
| 163 | return res |
| 164 | else: |
| 165 | return iterable_type(transform_tree(child, fn) for child in tree) |
| 166 | else: |
| 167 | return fn(tree) |
| 168 | |
| 169 | |
| 170 | def check_graphs(*args): |
no test coverage detected