在python中展平列表或元组。不确定错误是什么

时间:2017-08-01 08:45:28

标签: python

def flatten(t):
    list = []
    for i in t:
        if(type(i) != list and type(i) != tuple):
            list.append(i)
        else:
            list.extend(flatten(i))
    return list

这是我编写的用于展平列表或元组的函数,其类似于

l = ((5, (1,2), [[1],[2]]))

当我做的时候

flatten(l)

我希望得到一份清单

[5, 1, 2, 1, 2]

但我改为

[5, 1, 2, [[1], [2]]]

我不确定为什么会这样,因为

    else:
        list.extend(flatten(i))

这部分代码将通过递归调用来检索元组的第三个元素中的int,即[[1],[2]]。我在这里缺少什么?

由于

2 个答案:

答案 0 :(得分:3)

您已将内置list分配给函数中的列表实例,因此类型检查不再适用于列表对象。

您应该为累加器列表使用不同的名称,例如lst

def flatten(t):
    lst = []
    for i in t:
        if type(i) != list and type(i) != tuple:
            lst.append(i)
        else:
            lst.extend(flatten(i))
    return lst

OTOH,您可以使用isinstance一次性完成两项检查,这也可以确保您运行检查的对象实际上是类型:

...
if not isinstance(i, (list, tuple)):
    ...

答案 1 :(得分:2)

您屏蔽了名称list

list = []
...
    if(type(i) != list and ...

type(i)永远不会等于[]

为列表使用其他名称:

result = []

您还希望使用isinstance()代替type()进行相等性测试:

def flatten(t):
    result = []
    for i in t:
        if not isinstance(i, (list, tuple)):
            result.append(i)
        else:
            result.extend(flatten(i))
    return list

这会早些时候告诉你,你没有比较类型:

>>> list = []
>>> isinstance(['foo'], (list, tuple))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a type or tuple of types

抛出异常是因为[]不是类型。

您可以在此处使用生成器,以避免重复追加或扩展新的列表对象。如果您将isinstance()类型检查放在循环之外,您可以支持具有相同功能的非序列:

def flatten(t):
    if not isinstance(t, (list, tuple)):
        yield t
        return
    for i in t:
        yield from flatten(i)

result = list(flatten(some_sequence_or_single_value))