【问题标题】:How to use recursion in python to gather a nested list? [duplicate]如何在 python 中使用递归来收集嵌套列表? [复制]
【发布时间】:2016-03-02 17:24:47
【问题描述】:

这里是代码

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]])) 时,它会打印出完全相同的输入,这意味着代码什么都不做。我认为问题在于[] 括号,但我想不出一种消除方法。有人可以帮忙吗?

【问题讨论】:

  • 我看不到您的代码不起作用,请更具体!
  • 刚刚编辑过,很抱歉造成混乱
  • 你想做什么?要展平列表列表?
  • 将嵌套列表变成单个列表。即 [[1, 2, [3, 4], 5], 6] -> [1,2,3,4,5,6]
  • @DavidZemens 这仅适用于单个级别,OP 需要递归解决方案

标签: python list python-3.x recursion


【解决方案1】:

这应该会有所帮助:

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]

【讨论】:

  • 这会使一层嵌套变平,并且不处理顶级列表具有一些标量值和一些子列表的情况。这不是对flatten recipe from the itertools documentation 的有意义的改进;唯一的区别是它返回未修改的标量。
  • @ShadowRanger 我不同意。该示例已经显示了两级嵌套。
  • mtk99,我不明白反对票。对我来说看起来不错,我将投票赞成您的解决方案。如果有错,请大家在这里解释。
  • @mtk99:您的原始帖子(未显示在编辑历史记录中,因为没有进行投票或 cmets,但仍缓存在我的浏览器的另一个选项卡上)的理解为 return [item for sublist in obj for item in sublist],没有递归list_all 调用,唯一的例子是在 [[2,3],[4,5]] 上运行,它没有显示非均匀嵌套。这就是我反对的;你改变了它,所以它现在可以工作了,但你和我一样知道我在评论什么。
  • @ShadowRanger 您的评论是在我最后一次更改后几分钟出现的。不用担心这不是比赛
【解决方案2】:

与其构造一堆中间的lists,不如考虑使用生成器函数。特别是在 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))

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

例子:

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

【讨论】:

    【解决方案3】:

    类似的东西,抱歉没有经过测试,但很简单......

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-24
      • 2018-06-24
      • 2021-08-15
      • 2014-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多