簡體   English   中英

在python中遞歸地展平嵌套列表

[英]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)

所以,你試圖壓扁一個列表。 你走在正確的軌道上,但你犯了幾個錯誤。 他們來了。

  1. 在循環移動try-except 使用您的代碼,如果為一個元素TypeError ,則循環停止運行。 你不希望發生這種情況。

  2. 在嘗試中,你什么都不產生。 只進行函數調用。 你也應該從那里歸還一些東西。 我建議你yield from ,如果你有python3.3 +。

  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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM