我正在尝试使用递归函数来展平可能包含子列表项的已发送列表:
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, [...]]
为什么我为每个子列表获取[...]
,我怎样才能避免这样做?谢谢你的帮助。
答案 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