什么是优雅方法来检查对象是否是字符串列表列表,没有嵌套循环?可能这里必须是构造结构化迭代的传统方法。
这样的事情:
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)]))
我做了一些自制的函数式编程,现在它检查字符串列表的列表列表:
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)))
答案 0 :(得分:2)
lol = [["a", "b"], ["c"], ["d", "e"], [1]]
from itertools import chain
print isinstance(lol, list) and all(isinstance(items, list) \
and all(isinstance(item, str) for item in items) for items in lol)
答案 1 :(得分:1)
>>> lls = [ ["he","li"],["be","b"],["c","n","o"],["f","ne","na"] ]
>>> isinstance(lls,list) and all([ all(isinstance(y,str) for y in x) and isinstance(x,list) for x in lls])
True
>>> not_lls = [ ["he","li"],["be",1]]
>>> isinstance(lls,list) and all([ all(isinstance(y,str) for y in x) and isinstance(x,list) for x in not_lls])
False
>>> not_also_lls = [ ["he","li"],{}]
>>> isinstance(lls,list) and all([ all(isinstance(y,str) for y in x) and isinstance(x,list) for x in not_also_lls])
False
答案 2 :(得分:1)
以更通用的方式:
def validate(x, types):
if not isinstance(x, types[0]):
raise ValueError('expected %s got %s for %r' % (types[0], type(x), x))
if len(types) > 1:
for y in x:
validate(y, types[1:])
用法:
try:
validate(
[['a', 'b', 'c'], ['d', 1], 3, ['e', 2, 'f']],
[list, list, str])
except ValueError as e:
print e # expected <type 'str'> got <type 'int'> for 1
try:
validate(
[['a', 'b', 'c'], ['d', 'X'], 3, ['e', 2, 'f']],
[list, list, str])
except ValueError as e:
print e # expected <type 'list'> got <type 'int'> for 3
try:
validate(
[['a', 'b', 'c'], ['d', 'X'], ['3'], ['e', '2', 'f']],
[list, list, str])
except ValueError as e:
print e
else:
print 'ok' # ok
答案 3 :(得分:0)
平原直截了当:
def isListOfStrings(los):
return isinstance(los, list) and all(isinstance(e, str) for e in los)
def isListOfListOfStrings(lolos):
return isinstance(lolos, list) and all(isListOfStrings(los) for los in lolos)
print isListOfListOfStrings([["foo"]])
我不能在这推荐递归,因为外部的测试并不真正类似于内部的测试。如果递归的深度没有固定(如本例所示)并且每个级别的任务相似(这里不是这种情况),递归会更有用。