Revision 1884
Added by Aaron Marcuse-Kubitza almost 13 years ago
lib/collection.py | ||
---|---|---|
1 | 1 |
# Data structures |
2 | 2 |
|
3 |
import iters |
|
3 |
import lists |
|
4 |
import util |
|
4 | 5 |
|
5 |
def rmap(func, value): |
|
6 |
'''Recursively applies func to all members of value''' |
|
7 |
rmap_ = lambda v: rmap(func, v) |
|
8 |
if isinstance(value, dict): |
|
9 |
return dict(((k, rmap_(v)) for k, v in value.iteritems())) |
|
10 |
elif iters.is_iterable(value): return map(rmap_, value) |
|
11 |
else: return func(value) |
|
6 |
def rmap(func, value, levels=None): |
|
7 |
'''Recursively applies func to all members of value |
|
8 |
@param func(value, is_leaf):value |
|
9 |
''' |
|
10 |
expand = util.coalesce(levels, 1) > 0 and (lists.is_seq(value) |
|
11 |
or isinstance(value, dict)) # whether value would be expanded |
|
12 |
value = func(value, not expand) |
|
13 |
|
|
14 |
if expand: # does nothing if func() returned a type that won't be expanded |
|
15 |
levels = util.do_ignore_none(lambda v: v-1, levels) |
|
16 |
rmap_ = lambda v: rmap(func, v, levels) |
|
17 |
if lists.is_seq(value): value = map(rmap_, value) |
|
18 |
elif isinstance(value, dict): |
|
19 |
value = dict(((k, rmap_(v)) for k, v in value.iteritems())) |
|
20 |
|
|
21 |
return value |
Also available in: Unified diff
collection.py: rmap(): Treat only built-in sequences specially instead of iterables. Pass whether the value is a leaf to the func. Added option to only recurse up to a certain # of levels.