Building linked list abstraction using class 'list'
data model.
##################
# Linked List #
##################
#Representation - start
empty = 'empty'
def is_link(s):
""" s is a linked list if it is empty or a (first, rest) pair."""
return s == empty or (isinstance(s, list) and len(s) == 2 and is_link(s[1]))
#Constructor
def link(first, rest):
"""Construct a linked list from its first element and the rest."""
assert is_link(rest), "rest must be a linked list"
return [first, rest]
#Selector 1
def first(s):
"""Return a first element of a linked list s"""
assert is_link(s), "first only applies to linked lists."
assert s != empty, "empty linked list has no first element."
return s[0]
#Selector 2
def rest(s):
"""Return the rest of the elements of a linked list s."""
assert is_link(s), "rest only applies to linked lists."
assert s != empty, "empty linked list has no rest."
return s[1]
def isempty(s):
return s == 'empty'
#Representation - end
### +++ === Abstraction barrier === +++ ###
#Use(interface) - start
def create_linked_list(first, rest):
return link(first, rest)
def len_rlist(s):
"""Compute the length of the recursive list s"""
def compute_length(s, length):
if isempty(s):
return length
else:
return compute_length(rest(s), length + 1)
return compute_length(s, 0)
def getitem_rlist(s, i):
"""Return the element at index i of recursive list s"""
if i == 1:
return first(s)
else:
return getitem_rlist(rest(s), i-1)
def count(s, value):
"""Count the occurence of value in the list s """
def count_occurence(s, value, count):
if isempty(s):
return count
else:
if first(s) == value:
return count_occurence(rest(s), value, count + 1)
else:
return count_occurence(rest(s), value, count)
return count_occurence(s, value, 0)
#Use - end
#Constructor and Selector constitutes Abstract Data Type that supports below invariants:
#If a recursive list s is constructed from a first element f and a recursive list r, then
# • first(s) returns f, and
# • rest(s) returns r, which must be a list or 'empty'.
#Code using this abstraction
Lst = empty
Lst = create_linked_list(4, Lst) # Representation [4, 'empty']
Lst = create_linked_list(3, Lst) # Representation [3, [4, 'empty']]
Lst = create_linked_list(1, Lst) # Representation [1, [3, [4, 'empty']]]
Lst = create_linked_list(1, Lst) # Representation [1, [1, [3, [4, 'empty']]]]
print(count(Lst, 1))
Intention is to build a single linked list abstraction that has no correctness issues.
Are there any limitations in building this abstraction?