patternpythonMinor
Wikipedia Trie pseudocode in Python
Viewed 0 times
pseudocodewikipediapythontrie
Problem
I translated the Wikipedia pseudo-code into Python code (little changes only were required), but I do not like the end result, as it looks like C with all those while loops and counters.
The fact is that I cannot use a
I also added an
The trie built from
As you can see, the common letters at the start are written only once, and going vertically you can read the possible endings.
Let's say I want to find trance:
The output is kinda reversed, but I would like to keep it so for simplicity of implementation.
```
import doctest
class Trie:
"""
Implements a Trie (also known as "digital tree", "radix tree" or "prefix tree").
W
The fact is that I cannot use a
for loop as i is needed to preserve state between loops.I also added an
inspect method to actually see visually what is inside the trie.The trie built from
"trasaction", "transformation", "transmission", "trance", "trap", "trip" is printed as:e None
c None
n None
o None
i None
s None
s None
i None
m None
n None
o None
i None
t None
c None
a None
n None
o None
i None
t None
a None
m None
r None
o None
f None
s None
n None
p None
a None
p None
i None
r None
t NoneAs you can see, the common letters at the start are written only once, and going vertically you can read the possible endings.
Let's say I want to find trance:
e None < -- final
c None < -- semifinal
n None
o None
i None
s None
s None
i None
m None
n None
o None
i None
t None
c None
a None
n None
o None
i None
t None
a None
m None
r None
o None
f None
s None
n None < -- `n` is the needed letter
p None < -- `p` is not the needed letter, so we skip
a None < -- `a` is the needed letter
p None
i None < -- `i` is not the needed letter, so we skip
r None < -- We continue here (no choice but to)
t None < -- We start here (no choice but to)The output is kinda reversed, but I would like to keep it so for simplicity of implementation.
```
import doctest
class Trie:
"""
Implements a Trie (also known as "digital tree", "radix tree" or "prefix tree").
W
Solution
-
-
The point of static methods is that they can be called without an instance of the class. Your static methods expect an instance as the first argument. Thus they could be normal instance methods instead.
-
Here the first assignment is redundant. If
-
The
(Note that in a chained assignment like
-
You could also take advantage of
find is not correct. If the final character occurs elsewhere in the string, the method returns True at that point. You can fix this and simplify the code at the same time:@staticmethod
def find(trie, word):
for char in word:
if char in trie.child:
trie = trie.child[char]
else:
return False
return True-
The point of static methods is that they can be called without an instance of the class. Your static methods expect an instance as the first argument. Thus they could be normal instance methods instead.
-
Here the first assignment is redundant. If
dict lookup raises KeyError, that will occur before the assignment anyway, so the value of node is preserved even if you only use node = node.child[s[i]].try:
_ = node.child[s[i]]
node = node.child[s[i]]
i = i + 1
except KeyError:
break-
The
while loops can be changed to for loops like this for example:def insert(self, s, value = 0):
node = self
for i, char in enumerate(s):
try:
node = node.child[char]
except KeyError:
break
else:
i += 1
# (* append new nodes, if necessary *)
for char in s[i:]:
node.child[char] = node = Trie()
node.value = value(Note that in a chained assignment like
node.child[char] = node = Trie() the right-hand-side is evaluated first and then assigned to the targets from left to right)-
You could also take advantage of
collections.defaultdict and greatly simplify insert:def __init__(self):
self.child = collections.defaultdict(Trie)
def insert(self, s, value = 0):
node = self
for char in s:
node = node.child[char]
node.value = valueCode Snippets
@staticmethod
def find(trie, word):
for char in word:
if char in trie.child:
trie = trie.child[char]
else:
return False
return Truetry:
_ = node.child[s[i]]
node = node.child[s[i]]
i = i + 1
except KeyError:
breakdef insert(self, s, value = 0):
node = self
for i, char in enumerate(s):
try:
node = node.child[char]
except KeyError:
break
else:
i += 1
# (* append new nodes, if necessary *)
for char in s[i:]:
node.child[char] = node = Trie()
node.value = valuedef __init__(self):
self.child = collections.defaultdict(Trie)
def insert(self, s, value = 0):
node = self
for char in s:
node = node.child[char]
node.value = valueContext
StackExchange Code Review Q#106351, answer score: 7
Revisions (0)
No revisions yet.