[英]Recursively flatten nested list in python
我正在使用Python中的生成器,我正在嘗試使用簡單的遞歸方案來實現flatten-function 。 也就是說,一個函數將一個列表作為輸入,該列表可能包含子列表,並輸出一個只能在輸入的原子元素上迭代的可迭代對象。
因此, print(list(flatten([1,2,3,[4,5,6]])))
應返回包含[1,2,3,4,5,6]
。
我的嘗試如下:
def flatten(toflatten):
try:
for element in toflatten:
flatten(element)
except TypeError:
yield toflatten
因此,它應檢查其參數是否是可迭代對象 。 如果是這種情況,也可以對此對象進行遞歸 。 否則,將其作為原子元素 。
這不起作用並且flatten([1,2,3,[4,5,6]])
只返回一個空列表。
為什么會這樣? 特別是; 為什么它甚至沒有對此輸入執行遞歸函數調用? (我使用的是Python 3.5)
所以,你試圖壓扁一個列表。 你走在正確的軌道上,但你犯了幾個錯誤。 他們來了。
在循環內移動try-except
。 使用您的代碼,如果為一個元素TypeError
,則循環停止運行。 你不希望發生這種情況。
在嘗試中,你什么都不產生。 只進行函數調用。 你也應該從那里歸還一些東西。 我建議你yield from
,如果你有python3.3 +。
最后,在except
,你需要yield element
,而不是toflatten
。 不要產生整個列表。
def flatten(toflatten):
for element in toflatten:
try:
yield from flatten(element)
except TypeError:
yield element
這給了,
>>> list(flatten([1,2,3,[4,5,6]]))
[1, 2, 3, 4, 5, 6]
您已經使用了EAFP(比請求更容易請求寬恕),這很好。 這是一種方法(實際上我最喜歡的),但有一個缺點: 這會在字符串上崩潰。
還有另一種方法:LYBL(在你跳躍之前看)。 它包括更加謹慎,使用if
語句,因此不會引發錯誤。
def flatten(toflatten):
for element in toflatten:
if isinstance(element, list):
yield from flatten(element)
else:
yield element
哪個和以前一樣,並給出,
>>> list(flatten([1,2,3,[4,5,6]]))
[1, 2, 3, 4, 5, 6]
然而,這是有利的,因為僅在子列表上調用yield from
生成器委托的yield from
。 我提到它也適用於字符串元素嗎?
>>> list(flatten([1,2,3,[4,5,'abc']]))
[1, 2, 3, 4, 5, 'abc']
請注意,在任何一種情況下,如果您有遞歸定義的列表,則無限遞歸的警告。 例如, flatten
將因此類輸入而崩潰。
x = [1, 2, 3]
x.append(x)
flatten(x)
您最終會收到運行時錯誤:
RuntimeError: maximum recursion depth exceeded
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.