I don't see anything glaring, except for the
size method. It has 2 major flaws:
Every time you want to check the size, you must traverse the entire list, giving it a time complexity of
O(n) (linear). This would likely be an unacceptable complexity for real world use. I'd expect that a
size method would be
O(1), meaning the length of time the operation takes has nothing to do with the number of elements in the list. What if your list contained a million elements and you needed to repeatedly get the size of it?
It prints the size instead of returning it. Rarely should a method print its result; unless that's the sole purpose of the method. Return the result instead of printing it directly so the returned size can actually be used instead of just seen. If you want to print the data, print the return of the function instead. Let the caller of the function decide how the data is used instead of forcing it to be printed.
How can these points be fixed? Instead of calculating the size, give your list an
n_nodes (or similar) field, and increment it inside of
data = input("Add an element:")
node = Node()
node.data = data
node.next = self.head
self.head = node
self.n_nodes += 1 # Here
Then just change your
size method to return
n_nodes. Notice that the number of elements in the list has no effect on the time this method will take to finish:
Then just print the size at the call site:
elif menu == 3:
Now that I've looked over your
insert method though, it suffers from a similar problem: needless use of side-effects. Why ask for the data inside the method via
input instead of passing the data in? What if you want to insert data that came from the internet, or from the disk?
data parameter of the
insert method to pass the data in, and get rid of the call to
input. The data can still come from
input, just ask for it outside of the method.