【问题标题】:Python: multilevel nested lists [duplicate]Python:多级嵌套列表
【发布时间】:2012-11-16 10:08:53
【问题描述】:

可能重复:
Flatten (an irregular) list of lists in Python

示例 1:

假设我有一个列表:[[1,2],[3,4]]。我可以使用两个 for 循环来打印:1、2、3、4。

示例 2:

所以,现在让我们假设我得到了一个输出,但我不知道 list1 中有多少嵌套列表:

list1 = [1, [1, 2, [3, 5, 6,[ .. ], ..., ] ] ] ]

所以,我的问题是如何以与第一个示例相同的格式打印出每个单独的数字。我现在正在处理一些结果,它给了我嵌套列表,但是函数的不同输入会给我不同数量的嵌套列表。

我能想到的就是这样做,但是在isinstance部分之后不知道该怎么做:

c = 0
for i in list1:
   while c < len(list1):
         if isinstance(i, list):

         else:
              print i
         c += 1

谢谢

首次编辑

如果还有一种方法可以将所有嵌套列表解构为一个对我来说也可以的方法,但我很想知道这两个问题的答案。

【问题讨论】:

  • 哇,谢谢大家。下面的所有答案都对我有用,但如果我计算正确,artsiom 的算法 big o 应该是线性的,这对我来说是理想的,因为我实际上在列表中有数千个嵌套列表。
  • 太棒了。接受你最终使用的答案:)
  • 哦,等等,没关系。所有大 o 符号的解都是 n^n。
  • @TTT:取决于你如何定义 N。如果 N = 所有列表中的元素数,那么我的解决方案是 Python yield from,它允许直接屈服于顶部生成器,而无需通过递归返回。这也可以通过巧妙地使用迭代器在 Python

标签: python algorithm list loops python-2.7


【解决方案1】:

itertools documentation 有一些很好的迭代列表等示例,因此在面对此类任务时,它始终是一个很好的起点。

我会推荐使用生成器,它可以避免创建多个级别的列表:

def flatten_all(iterable):
    for elem in iterable:
        if not isinstance(elem, list):
            yield elem
        else:
            for x in flatten_all(elem):
                yield x
            # in Python 3.3 just: yield from flatten_all(elem)

应用:

for x in flatten_all([1, [2, [3]]]):
    print(x)

# or if you need a list:
my_lst = list(flatten_all([1, [2, [3]]])
assert my_lst == [1, 2, 3]

编辑:非递归线性版本

def flatten_all(iterable):
    stack = [iter(iterable)]
    while stack:
        try:
            elem  = stack[-1].next()
            if not isinstance(elem, list):
                yield elem
            else:
                stack.append(iter(elem))
        except StopIteration:
            stack.pop()

【讨论】:

  • 我相信这是正确的方法。通过查看它,我想它和我的解决方案一样快。但它也更加灵活,因为它正在构建一个生成器。
【解决方案2】:

这是一个使用递归的例子:

list1 = [1, [2,3,4], [5, 6, 7, [8, 9]]]

def print_list(l):
    for e in l:
        if type(e) == list:
            print_list(e)
        else:
            print e

print_list(list1)

【讨论】:

  • 您是否有机会知道递归的 bigo 表示法。如果我没看错,假设 len(list) = n.
  • 我相信计算机科学家会比这位牧师午休时更好地回答这个问题;)
  • 如你所说,这取决于你如何定义“n”。否则遍历树也是 n^n。但是对于树和这些列表(看起来像树,数据在叶子中),它被认为是线性的,因为通常,树节点被认为是数据元素(例如数据库中的多分支树,虽然它更多复杂,可能是 n=d*log(d) 其中 d 是索引中的实际数据输入(或键数)。
【解决方案3】:

您可以尝试这样的事情(代码使您的列表平放在一行中,以便您稍后打印):

def make_flat(arr):
    res = []
    for l in arr:
        if isinstance(l, list):# or isinstance(l, collections.Iterable)
            res.extend(make_flat(l)) 
        else:
            res.append(l)
    return res

flat = make_flat(list1)
for x in flat:
    print x

或者:

def make_flat(arr):
    return sum(map(lambda a: make_flat(a) if isinstance(a,(list)) else [a],arr),[])

【讨论】:

  • 有了这么大的列表,我会为不同的解决方案计时......
  • 是的,对 - 这就是为什么我喜欢有产量的解决方案,但它仍然在做 OP 想要的不是吗?它制作扁平列表并将其打印出来。没有人说它应该适用于大列表,对吧?
  • 是的! @TTT 在这里做了评论,然后他删除了(?)我的评论是对此的回应。这绝不是对您的解决方案的批评:)
  • @NiclasNilsson - 哦))我明白了)和平)))
猜你喜欢
  • 2018-04-05
  • 1970-01-01
  • 2020-10-29
  • 2018-07-14
  • 1970-01-01
  • 2019-02-24
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多