I'm currently implementing data structures and algorithms I studed in my college course. This is my implementation of a singly linked list and a stack. I would appreciate some feedback in terms of the code quality.
My LinkedList:
from random import randint
class Node:
def __init__(self, x):
self.current = x
self.next = None
class LinkedList:
def __init__(self, x):
self.head = Node(x)
def insert(self, x):
new_entry = Node(x)
new_entry.next = self.head
self.head = new_entry
def search(self, x):
node = self.head
while node.current is not x:
if node.next is None:
break
node = node.next
if node.current is x:
return x
else:
return None
def contains(self, x):
retrieved = self.search(x)
return retrieved is x
def delete(self, x):
try:
node = self.head
while node.next.current is not x:
node = node.next
if node.next.current is x:
node.next = node.next.next
except AttributeError:
print str(x) + " is not in the linked list"
def traverse(self):
node = self.head
text = "" # type: str
while node is not None:
text += str(node.current) + "->"
node = node.next
return text
My stack:
class Stack:
def __init__(self):
self.data = []
def push(self, e):
self.data.append(e)
def pop(self):
return self.data.pop()
def prnt(self):
print self.data
def is_integer(val):
try:
int(val)
return True
except ValueError:
return False
def is_binary_operator(val):
return val is '+' or val is '-' or val is '*' or val is '/'
def postfixEval(stack, expression):
symbols = expression.split()
for symbol in symbols:
if is_integer(symbol):
s = int(symbol)
stack.push(s)
elif is_binary_operator(symbol):
s2 = stack.pop()
s1 = stack.pop()
if symbol is '+':
a = s1 + s2
elif symbol is '-':
a = s1 - s2
elif symbol is '*':
a = s1 * s2
elif symbol is '/':
a = s1 / s2
stack.push(a)
return stack.pop()
-
3\$\begingroup\$ This should be 2 separate questions, shouldn't it? \$\endgroup\$Mast– Mast ♦2018年05月19日 21:27:19 +00:00Commented May 19, 2018 at 21:27
2 Answers 2
Notes on LinkedList
:
- The import is unused.
- It should allow creation of an empty list.
- Normally a linked list inserts items after the last item. Maybe I'm confused by the way
insert
works, but it looks like in your casehead
is always the last inserted entry in the list, and the list is traversed fromhead
backwards through history using.next
. delete
should usesearch
.
Notes on Stack
:
self.data
should beself.entries
or something else descriptive.prnt
should beas_string
or even__str__
.int(val)
does not check whether something is an integer, it just tries to convert a value to an integer.+
,-
,*
and/
are arithmetic, not binary, operators.- In Python 3 mathematical operators are modeled as functions.
is_integer
,is_binary_operator
andpostfixEval
should not be part ofStack
- they are not fundamental to the stack in any way.
-
\$\begingroup\$ '
int(val)
does not ...' No, but it does raise aValueError
if the argument can't be converted to an integer (which, when caught, results in the function returningFalse
). \$\endgroup\$Daniel– Daniel2018年05月20日 07:49:53 +00:00Commented May 20, 2018 at 7:49
def is_integer(val):
try:
int(val)
return True
except ValueError:
return False
Should be written:
def is_integer(val):
try:
int(val)
except ValueError:
return False
return True
This is cleaner because what may trigger the exception is not the return statement but when int()
tries to convert val
. Besides, maybe what you really are looking for is:
import numbers
def is_integer(val):
return isinstance(val, numbers.Integral)
This way, you do not have to worry about exceptions since they are managed under the hood and, I think that is also the data type you want to deal with.
def prnt(self): print self.data
A stack has push()
, pop()
and size()
operations, but nothing like prnt()
. If you need the functionality prnt() is doing, take advantage of the Python __repr__()
magic method instead:
def __repr__(self):
return '{} '.format(self.data)