使用递归反转列表中的列表
def is_list(p):
return isinstance(p, list)
def deep_reverse(p):
initial = []
for v, e in enumerate(p):
if is_list(e):
#print p[v][::-1]
initial.append(p[v][::-1])
deep_reverse(e)
return initial
p = [1, [2, 3, [4, [5, 6, [7, 8]]]]]
print deep_reverse(p)
我得到了 [[[4, [5, 6, [7, 8]]], 3, 2]]
,但我期待的结果至少是 [[[[6, 5, [8, 7]], 4], 3, 2]]
(我还没想明白怎么才能不丢掉最开始的那个列表 [1[...]]
)。
你可以看到,代码只反转了 [ [2, 3]]
,变成了 [[3, 2]]。我哪里出错了呢?我是不是没考虑到什么?
5 个回答
2
已经有很多不错的解决方案了,但也许这就是你想要的算法:
def is_list(p):
return isinstance(p, list)
def deep_reverse(p):
initial = p[::-1] # reverse this level
for v, e in enumerate(initial):
if is_list(e): # for all the sublist in this level
initial[v] = deep_reverse(e) # recursively call deep_reverse to reverse the sublist
return initial
p = [1, [2, 3, [4, [5, 6, [7, 8]]]]]
print deep_reverse(p)
3
这里有一个更通用、更符合Python风格的答案,基于Pavel Anossov的内容,具体如下:
def deep_reversed(seq):
return [deep_reversed(x) if (isinstance(x, collections.Sequence) and
not isinstance(x, str)) else x
for x in reversed(seq)]
请注意,这个答案适用于Python 3.x,如果你在用Python 2.x,应该使用isinstance(x, basestring)
,这样才能支持Unicode字符串。
这个答案很好,因为它可以正确处理任何像序列一样的对象——无论是列表、元组,还是自定义的类。这意味着它的适用性更广。
补充:如果你想让它内部反转字符串:
def deep_reversed(seq):
for x in reversed(seq):
if isinstance(x, collections.Sequence):
if isinstance(x, str):
yield "".join(reversed(x))
else:
yield deep_reversed(x)
else:
yield x
同样,在2.x中,使用isinstance(x, basestring)
。
5
我会这样做:
def deep_reverse(p):
return [deep_reverse(x) if isinstance(x, list) else x for x in p[::-1]]
p = [1, [2, 3, [4, [5, 6, [7, 8]]]]]
print deep_reverse(p) # [[[[[8, 7], 6, 5], 4], 3, 2], 1]