What is the elegant way to check if object is list of lists of strings, without nested loops? Probably here must be conventional ways to construct structured iterations.
UPD
Something like this:
l = [['a', 'b', 'c'], ['d', 1], 3, ['e', 2, 'f']]
def recurse(iterable, levels):
results = []
try:
fn = levels[0]
except IndexError:
return
for e in iterable:
results.append(fn(e))
try:
results.extend(recurse(e, levels[1:]))
except TypeError:
pass
return results
instance_of = lambda t: lambda e: isinstance(e, t)
print(recurse(l, [instance_of(list), instance_of(basestring)]))
UPD #2
Ive made some kind of homebrew functional programming, now it checks for list of lists of lists of strings:
from collections import Iterable
from itertools import imap, chain
def compose(f, g):
return lambda *a, **kw: f(g(*a, **kw))
def concat(iterable):
return chain.from_iterable(iterable)
def mk_iter(o):
if isinstance(o, Iterable):
return o
else:
return [o]
def put_in(f, g):
"""To support spirit of the Olympics :)"""
return lambda e: concat(
[mk_iter(f(e)),
concat(imap(compose(mk_iter, g), mk_iter(e)))]
)
ckr = lambda t: lambda e: isinstance(e, t)
l = [[['a', 'b'], ['c']], [['d'], ['1']], [1]]
fns = [ckr(list), ckr(list),ckr(list), ckr(str)]
fns.reverse()
print(list(reduce(lambda x, y: put_in(y, x), fns)(l)))
chainor similar) will only lead to hiding that fact.for's and nesting :)