Linked list in Python which gets values from keyboard What do you think about my implementation of linked list, which gets values from keyboard? I implemented three basic functions: print, insert and size.

class Node:

       def __init__(self):
               self.data = None
               self.next = None

class LinkedList:

       def __init__(self):
               self.head = None

       def insert(self,data):
               data = input("Add an element:")
               node = Node()
               node.data = data
               node.next = self.head
               self.head = node

       def print(self):
               print_list = self.head
               while print_list:
                       print(print_list.data)
                       print_list = print_list.next

       def size(self):
               i=0
               head = self.head
               while head:
                      i+=1
                      head = head.next
               print (i)


  MyList = LinkedList()

  while True:
       print("1. Add an element")
       print("2. Print the list")
       print("3. Size of the list")
       menu = int(input("Choose an action:"))

       if menu == 1:
               MyList.insert(1)
       elif menu == 2:
               MyList.print()
       elif menu == 3:
               MyList.size()
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 insert:

def insert(self,data):
    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:

def size(self):
    return self.n_nodes


Then just print the size at the call site:

...
elif menu == 3:
    print(MyList.size())


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?

Use the 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.