A big advantage of Python versus C# is not having to think about types unless you have to, and if the code is less verbose that's a side benefit. (And honestly, I'd be surprised to find a whole lot of C# code that couldn't be written to be more concise in Python, if performance wasn't an issue)
def foo(lst):
if type(lst) is str:
#return do_string_stuff_to(lst)
else:
#handle do_list_stuff_to(lst)
And I'm done. There's a good chance I'll throw the function away or re-write it before I ever care about the sort of edge cases that would get caught by a static compiler. If the algorithm works on a dictionary or set just as well as the list I had in mind, so much the better. In the meantime it's doing its work and helping me get other things done.
> If the algorithm works on a dictionary or set just as well as the list I had in mind, so much the better.
This is the key difference in attitude. I don't want a language that frictionlessly helps me screw up. If what I'm doing might work but nobody actually knows, I want some kind of warning. At the very least I need to add your code to my test coverage.