By using a : colon in the list index, you are asking for a slice, which is always another list. In Python you can assign values to both an individual item in a list, and to a slice of the list.
What is the difference between list [1] and list [1:] in Python?
The second, list(), is using the actual list type constructor to create a new list which has contents equal to the first list. (I didn't use it in the first example because you were overwriting that name in your code - which is a good example of why you don't want to do that!)
When reading, list is a reference to the original list, and list[:] shallow-copies the list. When assigning, list (re)binds the name and list[:] slice-assigns, replacing what was previously in the list. Also, don't use list as a name since it shadows the built-in.
The first way works for a list or a string; the second way only works for a list, because slice assignment isn't allowed for strings. Other than that I think the only difference is speed: it looks like it's a little faster the first way. Try it yourself with timeit.timeit () or preferably timeit.repeat ().
The notation List> means "a list of something (but I'm not saying what)". Since the code in test works for any kind of object in the list, this works as a formal method parameter. Using a type parameter (like in your point 3), requires that the type parameter be declared. The Java syntax for that is to put