任何人都可以提供有关如何进行python词典常见遍历的任何帮助或建议吗?
这是我的示例数据(遍历维基百科页面进行遍历)
TREEDATA = [['F', 'B', 'A'],
['F', 'B', 'D', 'C'],
['F', 'B', 'D', 'E'],
['F', 'G', 'I', 'H']]
我有一个简单的函数来从这个数据创建一个dict
def createTree(allTransactionsMatrix):
root = {}
for transaction in allTransactionsMatrix:
tempDict = root
for item in transaction:
tempDict = tempDict.setdefault(item, {})
return root
我成功地为这个词典创建了一个预订遍历。
def preOrderTraversal(pyTree):
for key, value in pyTree.items():
print(key)
if isinstance(value, dict):
preOrderTraversal(value)
所以当我跑...
import json
pyTree = createTree(TREEDATA)
print(json.dumps(pyTree, indent=5))
我收到一本很好的词典
{
"F": {
"B": {
"A": {},
"D": {
"C": {},
"E": {}
}
},
"G": {
"I": {
"H": {}
}
}
}
}
我可以获得这棵树的前序遍历
preOrderTraversal(pyTree)
带输出
F
B
A
D
C
E
G
I
H
然而,顺序和后序证明是困难的。
我对postorder的开始是在我访问它之后删除了一个叶子节点。然而,由于修剪/删除的工作原理,这并没有通过整个树。
def postOrderTraversal(pyTree):
for key, value in list(pyTree.items()):
if pyTree[key] == {}:
print(key)
del pyTree[key]
else:
postOrderTraversal(pyTree[key])
注意,我使用list(pyTree.items())
的原因是因为在python 3中你无法删除当前的迭代器。它会知道并抛出错误。所以转换成一个列表让我顺其自然。
感谢您的帮助!
答案 0 :(得分:0)
字典非常适合我发现的可视化,但对于遍历方法并不好。所以我实现了一个python树类,可以是二进制或n-ary(但不是二叉搜索树,值和类型无关紧要)。
以下是所有遍历方法的代码和示例输出等。
from queue import *
import json
import itertools
import math
class Node:
def __init__(self, val):
self.val = val
self.children = []
self.freq = 1
def get(self):
return self.val
def set(self, val):
self.val = val
def getChild(self, val):
for each in self.children:
if each.val == val:
return each
def getChildren(self):
childArray = []
for each in self.children:
childArray.append(each.val)
return childArray
def printStats(self):
print("Value: " + str(self.val) + " | " +
"Frequency: " + str(self.freq) + " | " +
"Children: " + ','.join(self.getChildren()))
class PythonTree:
def __init__(self):
self.root = Node("*root*")
self.totalTreeNodes = 1
self.totalInsertions = 1
self.treeDepth = 0
self.visualDict = {self.root.get()}
def setVisualDict(self, passedMatrix):
root = {}
for transaction in passedMatrix:
tempDict = root
for item in transaction:
tempDict = tempDict.setdefault(item, {})
self.visualDict = root
def addByMatrix(self, passedMatrix):
self.setVisualDict(passedMatrix)
for subArray in passedMatrix:
currentNode = self.root
tempLength = len(subArray)
if tempLength > self.treeDepth:
self.treeDepth = tempLength
for each in subArray:
self.totalInsertions += 1
if each in currentNode.getChildren():
currentNode = currentNode.getChild(each)
currentNode.freq += 1
else:
self.totalTreeNodes += 1
tempNode = Node(each)
currentNode.children.append(tempNode)
currentNode = tempNode
def preOrder(self, currentNode, retArray):
retArray.append(currentNode.get())
for each in currentNode.children:
self.preOrder(each, retArray)
return retArray
def preOrderTraversal(self):
return self.preOrder(self.root, [])
def inOrder(self, currentNode, retArray):
whole = len(currentNode.children)
half = math.ceil(whole / 2)
for each in itertools.islice(currentNode.children, 0, half):
self.inOrder(each, retArray)
retArray.append(currentNode.get())
for each in currentNode.children[half:]:
self.inOrder(each, retArray)
return retArray
def inOrderTraversal(self):
return self.inOrder(self.root, [])
def postOrder(self, currentNode, retArray):
for each in currentNode.children:
self.postOrder(each, retArray)
retArray.append(currentNode.get())
return retArray
def postOrderTraversal(self):
return self.postOrder(self.root, [])
def levelOrderTraversal(self):
currentNode = self.root
q = Queue()
q.put(currentNode)
output = []
while q.qsize() > 0:
currentNode = q.get()
output.append(currentNode.val)
for each in currentNode.children:
q.put(each)
return output
def getStatsTraversal(self):
currentNode = self.root
mostFrequent = []
leastFrequent = []
maxVal = currentNode.freq
minVal = currentNode.freq
q = Queue()
q.put(currentNode)
while q.qsize() > 0:
currentNode = q.get()
currentNode.printStats()
# Max Checks
if currentNode.freq > maxVal:
mostFrequent = [currentNode.get()]
maxVal = currentNode.freq
if currentNode.freq == maxVal:
if currentNode.get() not in mostFrequent:
mostFrequent.append(currentNode.get())
# Min Checks
if currentNode.freq < minVal:
leastFrequent = [currentNode.get()]
minVal = currentNode.freq
if currentNode.freq == minVal:
if currentNode.get() not in leastFrequent:
leastFrequent.append(currentNode.get())
for each in currentNode.children:
q.put(each)
return mostFrequent, leastFrequent, maxVal, minVal
def getTreeStats(self):
print("***Including the *root* node***\n")
mostFrequent, leastFrequent, maxVal, minVal = self.getStatsTraversal()
print("\nTotal Nodes: " + str(self.totalTreeNodes))
print("Total Insertions ( greater than or equal to total Nodes ): " + str(self.totalInsertions))
print("Depth of Tree: " + str(self.treeDepth))
print("Most Frequent Nodes: " + str(mostFrequent) + " appeared (" + str(maxVal) + ") time(s)")
print("Least Frequent Nodes: " + str(leastFrequent) + " appeared (" + str(minVal) + ") time(s)")
avg = float(self.totalInsertions / self.totalTreeNodes)
print("Average Node Frequency " + str(avg) + " (totalNodes/ totalInsertions")
print(json.dumps(self.visualDict, indent=5))
这是一个示例运行(来自wiki的相同节点,刚刚修改过)。
myTree = PythonTree()
myTree.addByMatrix([['F', 'B', 'A'],
['F', 'B', 'D', 'C'],
['F', 'B', 'D', 'E'],
['F', 'G', 'I', 'J'],
['F', 'G', 'I', 'H']])
print("\nPRE ORDER TRAVERSAL")
print(myTree.preOrderTraversal())
print("\nLEVEL ORDER TRAVERSAL")
print(myTree.levelOrderTraversal())
print("\nIN ORDER TRAVERSAL")
print(myTree.inOrderTraversal())
print("\nPOST ORDER TRAVERSAL")
print(myTree.postOrderTraversal())
print("\nTREE STATS")
myTree.getTreeStats()
以及相关的输出。
PRE ORDER TRAVERSAL
['*root*', 'F', 'B', 'A', 'D', 'C', 'E', 'G', 'I', 'J', 'H']
LEVEL ORDER TRAVERSAL
['*root*', 'F', 'B', 'G', 'A', 'D', 'I', 'C', 'E', 'J', 'H']
IN ORDER TRAVERSAL
['A', 'B', 'C', 'D', 'E', 'F', 'J', 'I', 'H', 'G', '*root*']
POST ORDER TRAVERSAL
['A', 'C', 'E', 'D', 'B', 'J', 'H', 'I', 'G', 'F', '*root*']
TREE STATS
***Including the *root* node***
Value: *root* | Frequency: 1 | Children: F
Value: F | Frequency: 5 | Children: B,G
Value: B | Frequency: 3 | Children: A,D
Value: G | Frequency: 2 | Children: I
Value: A | Frequency: 1 | Children:
Value: D | Frequency: 2 | Children: C,E
Value: I | Frequency: 2 | Children: J,H
Value: C | Frequency: 1 | Children:
Value: E | Frequency: 1 | Children:
Value: J | Frequency: 1 | Children:
Value: H | Frequency: 1 | Children:
Total Nodes: 11
Total Insertions ( greater than or equal to total Nodes ): 20
Depth of Tree: 4
Most Frequent Nodes: ['F'] appeared (5) time(s)
Least Frequent Nodes: ['*root*', 'A', 'C', 'E', 'J', 'H'] appeared (1) time(s)
Average Node Frequency 1.8181818181818181 (totalNodes/ totalInsertions
{
"F": {
"B": {
"A": {},
"D": {
"C": {},
"E": {}
}
},
"G": {
"I": {
"J": {},
"H": {}
}
}
}
}
如果您有任何疑问,请发表评论。我知道顺序遍历并不总是正确出现,但没有明确的方法来执行N-ary树的有序遍历。但其他方法应该是一致的。