[Tutor] Was: flatten a python list
Cameron Simpson
cs at cskk.id.au
Tue Jun 1 22:00:07 EDT 2021
On 02Jun2021 13:35, DL Neil <PyTutor at DancesWithMice.info> wrote:
>What happens if we broaden the original spec from "list" to strings (as
>above), and then continue into tuples, dictionary (keys or values),
>classes, etc?
>
>Is there a generic Python function which advises if a value is atomic or
>some form of container?
>(yes, could check for __contains__ method, but...)
I go with:
should_iterate = False
if not isinstance(obj, str): # known special case :-(
try:
it = iter(obj)
except TypeError:
pass
else:
should_iterate = True
Usually you have better knowledge about what's going on, or the function
spec mandates being given a sensible iterable etc.
You can do the same for sequences by trying obj[None] or something.
Hopefully these tests have no significant side effects, which is why
ideally you know more (i.e. your callers can be expected to give you the
right kind of thing), or mandate more (i.e. your caller's are buggy if
they give you the wrong thing).
Not so easy with generic stuff. Like list flatten in this example.
For an example where you are doing a genericish flatten but still expect
sensible inputs (but, still accepting str!), here's an example of mine:
https://hg.sr.ht/~cameron-simpson/css/browse/lib/python/cs/binary.py#L103
which flattens the return from a "transcribe" method common to a suite
of subclasses. For ease of implementation the transcribe methods can
return a variety of convenient to the implementor things, including
being generators yielding things.
You can see it does a getattr along the lines of your __contains__
check, but if otherwise rather opinionated: None, bytes, memoryview, str
are specially handled but otherwise we assume we've got an iterable. The
return from flatten() itself is an iterable - a flat iterable if
byteses.
Cheers,
Cameron Simpson <cs at cskk.id.au>
More information about the Tutor
mailing list