创建的嵌套/递归列表

时间:2018-10-22 10:46:16

标签: python list

如何递归创建列表?

我有此列表:

l = ['a', 'b', 'new', 'c', 'd', 'new', 'z', 'x', 'c', 'fin', 'f', 'fin', 
     'g', 'l', 'new', 'z', 'x', 'c', 'fin', 'j']

预期输出为:

r = ['a', 'b', ['c', 'd', ['z', 'x', 'c'] 'f'], 'g', 'l', ['z', 'x', 'c'] 'j']

到目前为止,我已经尝试过:

def asd(l, index=0):
    r = []
    for i in l[index:]:
        index += 1
        if i == 'new':
            i, index = asd(l, index)
        r.append(i)
        if i == 'fin':
            return r
    return r, index

r, index = asd(l)

我不明白如何使其工作。谁能帮我吗?

4 个答案:

答案 0 :(得分:2)

这是一种非递归解决方案,可以创建列表,一次性解析,而无需进行昂贵的index()操作:

l = ['a', 'b', 'new', 'c', 'd', 'new', 'f', 'fin', 'g', 'fin', 'j']

rv = []

curr = [rv]  # things are always added to the last element if not 'fin' or 'new'

for elem in l:
    if elem == "new":
        # create a new list, put it at end of curr 
        curr.append([])
        # add that list to the one before
        curr[-2].append(curr[-1])
    elif elem == "fin":
        # done, remove from curr
        curr.pop() 
    else:
        curr[-1].append(elem)

print(rv)

输出:

['a', 'b', ['c', 'd', ['f'], 'g'], 'j']

l = ['a', 'b', 'new', '1', '2', '3', 'fin', 'c', 'new', 'x', 'y', 'z', 'fin',]  

导致

['a', 'b', ['1', '2', '3'], 'c', ['x', 'y', 'z']]

您需要万无一失,以防不平衡/错误的new / fin


经过编辑,使其在Matthieu的评论后更加简洁。

答案 1 :(得分:2)

这是一种简单的递归解决方案,使用deque作为堆栈数据结构,可以从其中popleft from collections import deque def nest(lst): return _nest(deque(lst)) def _nest(deq): result = [] while deq: x = deq.popleft() if x == 'fin': break elif x == 'new': result.append(_nest(deq)) else: result.append(x) return result O(1)中最左边的元素。

算法

tests = [
    [],
    [1, 2, 3],
    [1, 2, 'new', 3, 4, 'fin', 5],
    [1, 2, 'new', 3, 4, 'fin', 5, 6, 'new', 7, 'fin'],
    ['new', 'fin', 'new', 'fin', 'new', 'new', 'fin', 'fin'],
    ['new', 1, 2, 'fin'],
    [1, 2, 3, 'new', 4, 'new', 5, 6, 'fin', 7, 8, 'fin', 9, 10, 'new', 11, 'fin', 12, 13]
]

for test in tests:
    print(nest(test))

测试

[]
[1, 2, 3]
[1, 2, [3, 4], 5]
[1, 2, [3, 4], 5, 6, [7]]
[[], [], [[]]]
[[1, 2]]
[1, 2, 3, [4, [5, 6], 7, 8], 9, 10, [11], 12, 13]

输出

.useXpath()     // every selector now must be XPath
.click("//a[text()='Two']")
.useCss()      // we're back to CSS now

答案 2 :(得分:1)

您可以改用堆栈,并遍历列表并使用它:

def parse(l):
    stack = [[]]

    for i in l:
        if i == "new":
            stack.append([])
        elif i == "fin":
            pop = stack.pop()
            stack[-1].append(pop)
        else:
            stack[-1].append(i)

    return stack[0]

答案 3 :(得分:1)

递归替代:

def asd(l):
    if 'new' in l:
        index_new = l.index('new')
        keyword = 1
        for index_fin,e in enumerate(l[index_new+1:], index_new+1):
            if e == 'new':
                keyword += 1
            elif e == 'fin':
                keyword -=1
            if not keyword:
                break
        return l[:index_new] + [asd(l[index_new+1:index_fin])] + asd(l[index_fin+1:])
    else:
        return l

输入:

['a', 'b', 'new', 'c', 'd', 'new', 'z', 'x', 'c', 'fin', 'f', 'fin', 
     'g', 'l', 'new', 'z', 'x', 'c', 'fin', 'j']

输出:

['a', 'b', ['c', 'd', ['z', 'x', 'c'], 'f'], 'g', 'l', ['z', 'x', 'c'], 'j']