[英]Flattening a list that contains lists of tuples, letters and integers
我需要遞歸整理列表:
在列表看起來像之前:
L=[1,[2,[‘a’,(3,’b’)]],(5,6),([11,22])]
后:
Lflat=[1,2,’a’,(3,’b’),(5,6),([11,22])]
我的代碼遇到問題(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
這將返回以下內容:
輸出: [1, 2, 'a', (3, 'b'), (5, 6), 11, 22]
這使我發現([])被認為是列表,而不是元組。
現在我的問題如下:
您的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
[]
。 這是因為默認args是在編譯函數時創建的,而不是在調用函數時創建的,並且如果我們為lst1
默認值[]
,則每次調用都會使用相同的列表。 看起來像第一次使用list_flatten
,我們可以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
保留了第一個調用的內容。 有關此重要主題的更多信息,請參見“最小驚訝”和可變默認參數 。 有時候,這種行為是可取的,但是在這種情況下,明智的做法是在代碼中添加注釋,而您有意使用可變的默認參數。
另一種方法是使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
產生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
您可以注意到,您需要的是:
在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:]))
它給出了預期的結果:
>>> 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.