[英]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)
請注意,這是對樹的深度優先搜索。
可能有更好的方法來包裝它,以便parseTree
是Node
的一種方法,但這應該給你一個想法。 當然,您仍然有一個問題,您要求用戶編寫 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.