Conversation
toolz/itertoolz.py
Outdated
|
|
||
|
|
||
| def flat(level, seq): | ||
| """ Flatten a possible nested sequence by n levels """ |
There was a problem hiding this comment.
I'll fill out this docstring soon.
There was a problem hiding this comment.
Cool. Don't forget to also point to concat(seq), which flattens a sequence one level.
|
Cool! Some questions:
|
toolz/itertoolz.py
Outdated
| if level < 0: | ||
| raise ValueError("level must be >= 0") | ||
| for item in seq: | ||
| if level == 0 or not hasattr(item, '__iter__'): |
There was a problem hiding this comment.
Probably better to have outside the for loop:
if level == 0:
yield from seq
returnThere was a problem hiding this comment.
Thanks! That works really well.
|
Yes, a very good use case for
def example_descend(x):
return not isinstance(x, (str, bytes, bytearray, dict))
def flatten(level, seq, descend=None):
""" Flatten a possible nested sequence by n levels """
if not callable(descend):
raise ValueError("descend must be callable boolean function")
if level < -1:
# -1 flattens infinitely.
raise ValueError("Level must be >=0 or -1")
def flat(level, seq):
if level == 0:
yield from seq
return
for item in seq:
if isiterable(item) and descend(item):
yield from flat(level - 1, item)
else:
yield item
yield from flat(level, seq)The descend function is only called on iterable items and returns True if the iterable should be unpacked. If this looks better to you, I can go ahead and commit it. @eriknw I really appreciate the feedback. |
flat -> flatten Allow -1 to for unregulated recursion Add UDF descend function to decide if itertable invokes recursive call. Add default descend function
|
@eriknw I think this is ready for another review. |
|
ping @eriknw |
| """ | ||
| if level < -1: | ||
| raise ValueError("Level must be >= -1") | ||
| if not callable(descend): |
There was a problem hiding this comment.
Maybe let users pass None for descend to say "I want the default value"?
| if not callable(descend): | |
| if descend is None: | |
| descend = _default_descend | |
| if not callable(descend): |
This is something I almost always recommend for default arguments, especially when the default value is private, like it is here.
Because
-
It can help code that programmatically selects the
descendargument. -
It can help with writing wrappers of
flattenwhich themselves let users pass an optionaldescend.
An implementation of javascript's Array.flat() (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat#use_generator_function)
More flexible than the
flattenrecipe in itertools.