Let's say I have a number of iterables:
[[1, 2], [3, 4, 5, 6], [7, 8, 9], [10, 11, 12, 13, 14]]
How can I get only each element that is the first to appear at its index in any of the iterables? In this case:
[1, 2, 5, 6, 14]
Visualized:
[1, 2]
[_, _, 5, 6]
[_, _, _]
[_, _, _, _, 14]
can it done in more functional style?
Sure, but I wouldn't. Davis Herring's approach is already lovely. Here's a "more functional" way, but more obscure to my eyes:
from itertools import zip_longest
SKIP = object()
def chain_suffixes(*iters):
return (next(a for a in s if a is not SKIP)
for s in zip_longest(*iters, fillvalue=SKIP))
print(list(chain_suffixes(
[1, 2], [3, 4, 5, 6], [7, 8, 9], [10, 11, 12, 13, 14])))
which prints
[1, 2, 5, 6, 14]
BTW, "more functional" may be in the eye of the beholder. To my eyes, various forms of generator comprehension are just as "functional" as other ways of spelling it. At an extreme, it's possible to rewrite the above without using comprehensions at all, or even typing "def".
from itertools import zip_longest
SKIP = object()
not_SKIP = lambda x: x is not SKIP
first_not_SKIP = lambda s: next(filter(not_SKIP, s))
chain_suffixes = lambda *iters: map(
first_not_SKIP,
zip_longest(*iters, fillvalue=SKIP))