[英]Flattening a list that contains lists of tuples, letters and integers
I need to flatten a list recursively: 我需要递归整理列表:
Before the list looks like: 在列表看起来像之前:
L=[1,[2,[‘a’,(3,’b’)]],(5,6),([11,22])]
After: 后:
Lflat=[1,2,’a’,(3,’b’),(5,6),([11,22])]
I've come across an issue with my code (lst1 is an empty lst1) 我的代码遇到问题(lst1为空的lst1)
def list_flatten(lst,lst1):
for item in lst:
if type(item) == tuple:
print(item)
lst1.append(item)
elif type(item) == list:
list_flatten(item,lst1)
else:
lst1.append(item)
return lst1
This returns the following: 这将返回以下内容:
OUTPUT : [1, 2, 'a', (3, 'b'), (5, 6), 11, 22]
输出:
[1, 2, 'a', (3, 'b'), (5, 6), 11, 22]
Which lead me to find out that ([]) is considered a list, not a tuple. 这使我发现([])被认为是列表,而不是元组。
Now my questions are as following: 现在我的问题如下:
Your list_flatten
function mutates the lst1
argument, so you don't really need to return anything. 您的
list_flatten
函数会lst1
参数,因此您实际上不需要返回任何内容。 You can call it like this: 您可以这样称呼它:
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)
output 产量
[1, 2, 'a', (3, 'b'), (5, 6), 11, 22]
It's recommended to use isinstance
rather than type
because that makes the code more versatile: it will also work with objects derived from list
. 建议使用
isinstance
而不是type
因为这会使代码更具通用性:它也可用于源自list
对象。
We can re-write the function so that you don't need to pass in lst1
: 我们可以重新编写该函数,以便您无需传递
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)
We give lst1
a default value of None
and on the top level of the recursion we re-bind the name lst1
to an empty list to collect the results. 我们给
lst1
一个默认值None
,在递归的顶层,我们将名字lst1
重新绑定到一个空列表中以收集结果。
We can't give lst1
a default value of []
. 我们不能将
lst1
的默认值lst1
[]
。 That's because default args are created when the function is compiled, not when the function is called, and if we gave lst1
a default value of []
that same list would get used on every call. 这是因为默认args是在编译函数时创建的,而不是在调用函数时创建的,并且如果我们为
lst1
默认值[]
,则每次调用都会使用相同的列表。 It would look like it does what we want the first time we used list_flatten
, but it would not behave as desired on subsequent calls. 看起来像第一次使用
list_flatten
,我们可以list_flatten
它,但是在随后的调用中却无法达到预期的效果。 Here's a short demo. 这是一个简短的演示。
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)
output 产量
[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]
As you can see, lst1
has retained its contents from the first call. 如您所见,
lst1
保留了第一个调用的内容。 For more info on this important topic, please see “Least Astonishment” and the Mutable Default Argument . 有关此重要主题的更多信息,请参见“最小惊讶”和可变默认参数 。 There are times when this behviour is desirable, but in such cases it's wise to add a comment to your code that you're intentionally using a mutable default argument.
有时候,这种行为是可取的,但是在这种情况下,明智的做法是在代码中添加注释,而您有意使用可变的默认参数。
Yet another way is to make list_flatten
into a generator, and collect its output into a list: 另一种方法是使
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)
In recent versions of Python you can replace list(list_flatten(L))
with [*list_flatten(L)]
. 在最新版本的Python中,您可以使用
[*list_flatten(L)]
替换list(list_flatten(L))
。
Python 2 doesn't have yield from
, but you can replace that line with: Python 2没有
yield from
产生yield from
,但是您可以将该行替换为:
for u in list_flatten(item):
yield u
If you don't actually need the list you can call the generator like this: 如果您实际上不需要此列表,则可以这样调用生成器:
for u in list_flatten(L):
print(u)
output 产量
1
2
a
(3, 'b')
(5, 6)
11
22
You can note that what you need is: 您可以注意到,您需要的是:
In Python code, it leads to: 在Python代码中,它导致:
def flatten(L):
if len(L) == 0: return L
elif len(L) == 1 and not isinstance(L[0], list): return L
else:
return (flatten(L[0] if isinstance(L[0], list)
else [L[0]]) + flatten(L[1:]))
it gives as expected: 它给出了预期的结果:
>>> L = [1, 2, 'a', (3, 'b'), (5, 6), ([11, 22],)]
>>> flatten(L)
[1, 2, 'a', (3, 'b'), (5, 6), ([11, 22],)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.