"""Mutable Linked Lists""" class Link: empty = () def __init__(self, first, rest=empty): if not (rest is Link.empty or isinstance(rest, Link)): raise ValueError('rest must be Link or empty') self.first = first self.rest = rest def __repr__(self): if self.rest is Link.empty: return 'Link({})'.format( self.first) else: return 'Link({}, {})'.format( self.first, repr(self.rest)) def __len__(self): return 1 + len(self.rest) # Where's the base case?? def __getitem__(self, i): if i == 0: return self.first elif self.rest is Link.empty: raise IndexError('linked list index out of range') else: # return self.rest.__getitem__(i-1) return self.rest[i-1] def __setitem__(self, i, val): if i == 0: self.first = val elif self.rest is Link.empty: raise IndexError('linked list assignment index out of range') else: self.rest[i-1] = val def map(self, f): self.first = f(self.first) if self.rest is not Link.empty: self.rest.map(f) def __contains__(self, e): if self.first == e: return True elif self.rest is Link.empty: return False else: return e in self.rest @property def second(self): return self.rest.first @second.setter def second(self, value): self.rest.first = value def create_long_ll(n): head = Link.empty while n > 0: head = Link(n, head) n -= 1 return head # Last demo s = Link(1, Link(2)) t = Link(3, Link(4)) s.first = 10 # mutate s s.rest.rest = t # change pointer s u = Link(1) u.rest = u # self referencing u.first u.rest.first u.rest.rest.first v = Link(s, t) v t.first = 30 # affects both v