您的list_flatten
函数改变了lst1
的参数,所以您并不需要返回任何东西。你可以这样调用:
L = [1,[2,['a',(3,'b')]],(5,6),([11,22])]
def list_flatten(lst, lst1):
for item in lst:
if isinstance(item, list):
list_flatten(item, lst1)
else:
lst1.append(item)
Lflat = []
list_flatten(L, Lflat)
print(Lflat)
输出
[1, 2, 'a', (3, 'b'), (5, 6), 11, 22]
我们推荐使用isinstance
,而不是type
,因为这使代码更灵活:它也将与list
派生对象。
我们可以重新写的功能,使您不必在lst1
经过:
def list_flatten(lst, lst1=None):
if lst1 is None:
lst1 = []
for item in lst:
if isinstance(item, list):
list_flatten(item, lst1)
else:
lst1.append(item)
return lst1
Lflat = list_flatten(L)
print(Lflat)
我们给lst1
的None
和我们递归的最高级别重新绑定默认值名称lst1
到一个空的列表来收集结果。
我们不能给lst1
默认值[]
。这是因为默认参数是在编译函数时创建的,而不是在函数被调用时创建的,并且如果我们给lst1
默认值[]
,那么在每次调用时将使用相同的列表。它看起来像我们第一次使用list_flatten
时所做的那样,但在随后的调用中它不会像预期的那样运行。这是一个简短的演示。
L = [1,[2,['a',(3,'b')]],(5,6),([11,22])]
def list_flatten(lst, lst1=[]):
for item in lst:
if isinstance(item, list):
list_flatten(item, lst1)
else:
lst1.append(item)
return lst1
Lflat = list_flatten(L)
print(Lflat)
Lflat = list_flatten(L)
print(Lflat)
输出
[1, 2, 'a', (3, 'b'), (5, 6), 11, 22]
[1, 2, 'a', (3, 'b'), (5, 6), 11, 22, 1, 2, 'a', (3, 'b'), (5, 6), 11, 22]
正如你所看到的,lst1
已经从第一个呼叫保留其内容。有关此重要主题的更多信息,请参阅“Least Astonishment” and the Mutable Default Argument。有些时候这种行为是可取的,但在这种情况下,向代码添加注释是明智的,即您有意使用可变默认参数。
还有一种方法是使list_flatten
成发电机,并收集其输出到一个列表:
def list_flatten(lst):
for item in lst:
if isinstance(item, list):
yield from list_flatten(item)
else:
yield item
Lflat = list(list_flatten(L))
print(Lflat)
在最新版本的Python可以用[*list_flatten(L)]
取代list(list_flatten(L))
。
Python 2里没有yield from
,但你可以替换该行:
for u in list_flatten(item):
yield u
如果你实际上并不需要的列表,你可以调用发电机是这样的:
for u in list_flatten(L):
print(u)
输出
1
2
a
(3, 'b')
(5, 6)
11
22
'([])'是一个列表,因为[元组由数值的由逗号分隔的](https://docs.python.org/2/tutorial /datastructures.html#tuples-and-sequences),并且这里没有逗号。在这种情况下,括号只是强制评估*里面的*括号,它是一个列表。 –
'([],)'是一个元组。别担心,这让每个人都感到困惑。 –
@DavidZemens确实如此,但函数会改变'lst1',所以它确实不需要返回任何东西。 –