问题
假设我有一个包含两个元素元组的列表,这两个元素元组由进一步嵌套的元组、元组列表或字符串组成。
samp = [('coor', [('test', 'correlation'),
[('another', [('nest', 'one')]), ('tags', 'list')], ('threshold', 'foo')])]
>>> samp
[('coor',
[('test', 'correlation'),
[('another', [('nest', 'one')]), ('tags', 'list')],
('threshold', 'foo')])]
我还有一个类,
Foo
,它只能正确地接受一个不包含任何嵌套列表,但可以包含其他Foo
的列表。class Foo:
def __init__(self, li):
self.l = li
def __repr__(self):
return 'Foo<{0}>'.format(str(self.l))
我想把我的嵌套结构转换成一个巨大的有效结构
>>> big_foo
Foo<[('coor',
Foo<[('test', 'correlation'),
Foo<[('another',
Foo<[('nest', 'one')]>),
('tags', 'list')]>,
('threshold', 'foo')]>
)]>
我怎样才能有效地做到这一点?
我的想法
显然,我必须从最深的嵌套列表中构建
samp
对象。我知道我可以检查元素是元组还是列表def is_seq(el):
return isinstance(el, collections.abc.Sequence) and not isinstance(el, str)
我可以检查iterable是否包含某种嵌套级别的列表
def contains_list(it):
return any(isinstance(el, list) or (isinstance(el, tuple) and contains_list(el))
for el in it)
我正在努力的是如何有效地构建我的新结构,因为元组是不可变的递归地从内到外构建结构似乎是不可能的,因为元组,所以我真的失去了一个好的方法。如果有什么抽象或模块可以为我简化这个问题,我很乐意接受。
动力
我试图用pyRserve包装一个r库,并需要r中嵌套的命名成员列表的可序列化python表示。pyrserve唯一可以序列化的类似内容是不支持构造时嵌套的TaggedList,所以现在我只剩下这个问题了。
最佳答案
比如说:
class Foo:
def __init__(self, li):
self.l = li
def __repr__(self):
return 'Foo<{0}>'.format(str(self.l))
def make_Foo(obj):
if isinstance(obj, list):
return Foo([make_Foo(item) for item in obj])
elif isinstance(obj, tuple):
return tuple(make_Foo(item) for item in obj)
elif isinstance(obj, str):
return obj
else:
raise Exception("Not implemented for type {}".format(type(obj)))
samp = [('coor', [('test', 'correlation'),
[('another', [('nest', 'one')]), ('tags', 'list')], ('threshold', 'foo')])]
x = make_Foo(samp)
print(x)
输出:
Foo<[('coor', Foo<[('test', 'correlation'), Foo<[('another', Foo<[('nest', 'one')]>), ('tags', 'list')]>, ('threshold', 'foo')]>)]>
如果你加上一些空格…
Foo<[('coor',
Foo<[('test', 'correlation'),
Foo<[('another',
Foo<[('nest', 'one')]>),
('tags', 'list')]>,
('threshold', 'foo')]>
)]>
与您期望的输出非常相似。