簡體   English   中英

在沒有 isinstance() 的列表上遞歸

[英]Recursion over a list of lists without isinstance()

我剛剛讀過“isinstance() 被認為有害” ,這似乎是合理的。 簡而言之,它主張避免使用這個 function。

好吧,剛才我碰巧正在編寫一個程序,該程序接受結構為樹的輸入,並且需要樹的結構信息。 沒有時間實現 GUI,我強迫用戶將其寫入配置文件(我知道這是一個糟糕的界面,但時間安排真的很緊)。 我的用戶技術性很強,但不一定知道 python。 我選擇該文件將包含代表輸入樹的列表列表(列表列表等),最終元素是樹的葉節點。 我認為這比將字典的合成器強加給用戶要好得多。

我計划遞歸解析列表如下(省略樹結構的使用,讓我們簡化並說必須在每個葉節點上調用treatLeafNode()):

def parseTree(input):
    if isinstance (input, list):
        for item in input:
            parseTree(item)
    else:
        treatLeafNode(item)

根據這篇文章,我想知道是否有一種簡單的方法可以在不使用 isinstance() 的情況下對其進行遞歸......

有人知道嗎?

您的情況是我會使用isinstance的情況之一。 您的數據結構受到很好的約束,您需要區分列表而不是列表。 使用isinstance來詢問它是否是一個列表。 你沒有說,但我想字符串可能在你的樹的葉子中,並且它們像列表一樣是可迭代的,所以用鴨子打字的方式區分它們是很繁瑣的。

你可以使用

def parseTree(input):
    try:
        for item in input:
            parseTree(item)
    except TypeError:
        treatLeafNode(item)

請注意,這也會迭代字符串。

更好的方法是用一個節點 object 封裝你的樹結構,它可以保存一個值和一個子列表:

class Node(object):
    def __init__(self, children=[], value=None):
        self.children = children
        self.value = value
    def isLeaf(self):
        return len(self.children) == 0

現在一個節點明確地要么是一個有值的葉子,要么是一個有孩子的元素(從技術上講,在這個例子中,非葉子節點也可以有值,但是你的應用程序代碼可以選擇強制非葉子節點永遠沒有值)。 parseTree可以寫成:

def parseTree(node):
    if node.isLeaf():
        treatLeafNode(node)
    else:
        for child in node.children:
            parseTree(child)

請注意,這是對樹的深度優先搜索。

可能有更好的方法來包裝它,以便parseTreeNode的一種方法,但這應該給你一個想法。 當然,您仍然有一個問題,您要求用戶編寫 Python 代碼,它是作為輸入的列表列表,並將其解析為上述樹結構,您需要使用isinstance 也許 yaml 將是描述語言的更好選擇,因為用戶不能在您的輸入中注入任意 Python 代碼?

使用 yaml 怎么樣? 您也不必自己進行驗證和解析邏輯。

樹可能看起來像

- [[aMAN],[sTACK, OVER],[FLOW]]
- [[aMAN1],[sTACK1, OVER1],[FLOW1]]
- [[aMAN2],[sTACK2, OVER2],[FLOW2]]

解析它的代碼

import yaml                    
f= open('test.yml')
test = yaml.load(f.read())
print test

Output:

[[['aMAN'], ['sTACK', 'OVER'], ['FLOW']], [['aMAN1'], ['sTACK1', 'OVER1'], ['FLOW1']], [['aMAN2'], ['sTACK2', 'OVER2'], ['FLOW2']]]

您選擇列表列表作為首選樹結構是否有原因? 我可以想到許多更好的方法來在配置文件中編寫一個。 假設您正在嘗試編碼:

a
|-- b
|   |-- c
|   |-- d
|   |   |-- e
|   |   `-- f
|   `-- g
|       `-- h
|-- i
`-- j
    `-- k

怎么樣

a: b, i, j
b: c, d, g
d: e, f
g: h
j: k

你可以很容易地把它解析成字典,然后把它連接成一棵樹。 事實上,我認為ConfigParser已經為您完成了。

否則,如何:

a
----b
--------c
--------d
------------e
------------f
--------g
------------h
----i
----j
--------k

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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