[英]Cannot remove item from nested list using recursion in Python
如標題所述。 我正在嘗試使用遞歸遍歷列表,並刪除列表中包括給定數字的任何數字(包括嵌套列表)。 這是我到目前為止的內容:
def deepRemoveAll(e, L):
if len(L) == 0:
return L
if type(L[0]) == type([]):
return deepRemoveAll(e, L[0])
if e == L[0]:
L.pop(0)
return deepRemoveAll(e, L)
if e != L[0]:
temp = L[0]
L.pop(0)
return [temp] + deepRemoveAll(e, L)
print(deepRemoveAll(47, [42, 47, [1, 2, [47, 48, 49], 50, 47, 51], 52]))
代碼對我來說似乎完美無缺,但是由於某種原因,該函數返回了列表[42,1,2,48,49]。 這是不正確的,因為在這種情況下,我需要刪除的只是其中包含的所有47,但同時也刪除了50、51和52。嵌套列表也需要保持原樣,但這將所有內容組合為一個,我不能刪除我的生活弄清楚為什么。
這應該有助於:
def deep_remove_all(e, a_list):
res = []
for item in a_list:
if isinstance(item, list):
res.append(deep_remove_all(e, item))
elif item != e:
res.append(item)
return res
您也可以這樣寫:
def deep_remove_all(e, a_list):
res = []
for item in a_list:
if item == e:
continue
res.append(
deep_remove_all(e, item)
if isinstance(item, list)
else item
)
return res
看這兩行:
if type(L[0]) == type([]):
return deepRemoveAll(e, L[0]);
您在這里說的是:
如果列表的第一個元素是列表,則在該列表上遞歸並丟棄該列表的其余元素。
例如,如果您有L=[[1,2],3]
, if type(L[0]) == type([])
檢查將返回true,並且您會說deepRemoveAll(e, [1,2])
,無論e
是什么,3都不見了。
只需更改return deepRemoveAll(e, L[0]);
到L[0] = deepRemoveAll(e, L[0])
,以便列表的第一個元素變成自身,而所有47都被刪除,然后繼續其余的邏輯。
讓我們看一下您的代碼,找到一些要修復的東西:
def deepRemoveAll(e, L):
if len(L) == 0:
return L;
if type(L[0]) == type([]):
return deepRemoveAll(e, L[0]);
if e == L[0]:
L.pop(0);
return deepRemoveAll(e, L);
if e != L[0]:
temp = L[0];
L.pop(0);
return [temp] + deepRemoveAll(e, L);
print(deepRemoveAll(47, [42, 47, [1, 2, [47, 48, 49], 50, 47, 51], 52]));
我看到的第一件事只是一個小問題: type([])
。 在現代Python中,這就是list
。
但是在我們更改它之前,我注意到您正在使用L[0]
做很多事情,並且幾乎總是pop
它。 讓我們變得常見:
def deepRemoveAll(e, L):
if len(L) == 0: return L
l0 = L.pop(0)
現在我們有了l0(因此不再重復索引)了。 我們可以決定是否放回它。
if type(l0) == list:
這將修復上面的type([])
。 但是,如果第一個元素是子列表,我們該怎么辦? 顯然,我們用第一個元素的深化版本替換了第一個元素:
if type(l0) == list:
l0 = deepRemoveAll(e, l0)
它仍然將是第一個元素,但是現在我們知道它是干凈的。
下一步是檢查l0是否是我們要刪除的e
。 如果是這樣, 則無需替換列表的開頭-您只需返回清理后的余數即可。 沒錯,並且作為子列表也是互斥的,因此我們可以使用else
或elif
:
elif l0 == e:
return deepRemoveAll(e, L)
最后,有l0 != e
。 在這種情況下,我們要清潔其余的L,並將l0值重新貼在前面。
可是等等! 在l0是列表的情況下,這也是我們想要做的,還記得嗎? 到目前為止,我們所做的只是清除l0。
因此,讓我們脫離if / elif,以便可以將頂部代碼(l0是一個列表)與我們未放入的else
代碼合並:l0!= e。
return [l0] + deepRemoveAll(e, L)
總結一下:
def deepRemoveAll(e, L):
if len(L) == 0: return L
l0 = L.pop(0)
if type(l0) == list:
l0 = deepRemoveAll(e, l0)
elif l0 == e:
return deepRemoveAll(e, L)
return [l0] + deepRemoveAll(e, L)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.