为什么扁平列表中的空白项目

时间:2017-11-30 17:18:53

标签: python python-3.x list recursion flatten

我正在尝试使用递归函数来展平可能包含子列表项的已发送列表:

def myflatten(slist, outlist=[]):
    for sl in slist:
        if type(sl) == list:    
            outlist.append(myflatten(sl, outlist))
        else: 
            outlist.append(sl)
    return outlist

print("myflatten list=", myflatten([1,[5,6,7],3,4,[7,8,9]]))

输出:

myflatten list= [1, 5, 6, 7, [...], 3, 4, 7, 8, 9, [...]]

为什么我为每个子列表获取[...],我怎样才能避免这样做?谢谢你的帮助。

4 个答案:

答案 0 :(得分:2)

现有的答案为自我引用的原因提供了很好的解释,但是他们对代码的建议修订对于解决等待咬你的default mutable argument gotcha没有任何作用。

这是一个不需要outlist参数的解决方案:

def myflatten(slist):
    outlist = []
    for sl in slist:
        if isinstance(sl, list):    
            outlist.extend(myflatten(sl))
        else: 
            outlist.append(sl)
    return outlist

print("myflatten list=", myflatten([1,[5,6,7],3,4,[7,8,9]]))

答案 1 :(得分:1)

问题是myflatten正在返回一个列表。因此,当您将myflatten的结果附加到outlist时,它会附加一个列表。尝试将outlist设置为等于myflatten的结果:

def myflatten(slist, outlist=[]):
    for sl in slist:
        if type(sl) == list:    
            outlist = myflatten(sl, outlist) #HERE IS THE CHANGE
        else: 
            outlist.append(sl)
    return outlist

print("myflatten list=", myflatten([1,[5,6,7],3,4,[7,8,9]]))

答案 2 :(得分:1)

您已创建了无限列表。列表中的[...]条目指向列表本身。有关详细信息,请参阅this answer

这是因为当你进行递归调用时,你传入outlist对象本身,然后将其返回并附加到自身。一个微妙的问题!但很容易解决;您希望使用=进行递归调用,而不是append。或者也许extend,并传入一个空列表。

def myflatten(slist):
    outlist = []
    for sl in slist:
        if type(sl) == list:    
            outlist.extend(myflatten(sl))
        else: 
            outlist.append(sl)
    return outlist

你甚至可以摆脱一个参数,这很好。

答案 3 :(得分:1)

另一个不使用list.extend的选项。我稍微重新安排了您的代码,并尝试避免使用默认参数:

def myflatten(slist):
    flat = []
    if isinstance(slist, list):
        for item in slist:
            flat += myflatten(item)
    else:
        flat.append(slist)
    return flat