如何在python中使用递归来收集嵌套列表?

时间:2016-03-02 17:24:47

标签: python list python-3.x recursion

这是代码

def list_all(obj):
    """
    Return a list of all non-list elements in obj or obj's sublists, if obj is a list. Otherwise, return a list containing obj.

    @param list|object obj: object to list
    @rtype: list

    >>> obj = 17
    >>> list_all(obj)
    [17]
    >>> obj = [1, 2, 3, 4]
    >>> list_all(obj)
    [1, 2, 3, 4]
    >>> obj = [[1, 2, [3, 4], 5], 6]
    >>> all([x in list_all(obj) for x in [1, 2, 3, 4, 5, 6]])
    True
    >>> all ([x in [1, 2, 3, 4, 5, 6] for x in list_all(obj)])
    True
    """
    if not isinstance(obj, list):
        return obj
    else:
        return [list_all(x) for x in obj]

当我尝试print(list_all([[2,3],[4,5]]))时,它打印出完全相同的输入,这意味着代码什么都不做。我认为问题是[]括号,但我想不出一种消除方法。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

这应该有所帮助:

def list_all(obj):
    if not isinstance(obj, list):
        return [obj]
    else:
        return [item for sublist in obj for item in list_all(sublist)]        

print(list_all(1))                   # Scalar
print(list_all([[2,3],[4,5]]))       # One level
print(list_all([[2,[3,2]],[4,5]]))   # Two levels

输出:

 [1]
 [2, 3, 4, 5]
 [2, 3, 2, 4, 5]

答案 1 :(得分:1)

不要构造一堆中间list,而应考虑使用生成器函数。特别是在Python 3.3+中,代码非常简单:

def flatten_lists(items):
    if isinstance(items, list):
        for x in items:
            yield from flatten_lists(x)
    else:
        yield items

如果您需要最终结果为list,您可以让调用者自己换行list(),或者定义一个包装器来调用生成器并将其转换为list对他们来说:

def list_all(items):
    return list(flatten_lists(items))

与非基于非生成器的解决方案相比,它显着减少了创建和处理所有中间list所涉及的分配器流失。

示例:

>>> list_all([1, [2, [3, [4, 5], 6]]])
[1, 2, 3, 4, 5, 6]

答案 2 :(得分:0)

像这样的东西,抱歉没有经过测试,但是微不足道......

def list_all(obj):

    result= []
    if not isinstance(obj, list):
        result.append(obj)
    else:
        for x in obj:
            result += list_all( x )
    return result