It's not a matter of in-place mapping, but if I remember correctly, map() returns a generator in Python3, which has the effect of simulating single-traversal and lazy evaluation like Haskell does.
> mutability is a property of data-structures, not of functions
True, but in a (purely) functional language, if all data structures are immutable and functions are simply mappings of input values to output values with no side-effects, that's inconsequential. We're talking about simulating a functional paradigm within a non-functional language with mutable data structures, so writing functions without side-effects would be more idiomatic - hence the problems with trying to write Python in a functional style.
If Python were a non-functional language, as you claim, it wouldn't have map reduce and functools. Python is not a purely functional language, it is a multi paradigm language. This difference is the main point here.
No, that would go against the philosophy of Python: only one [obvious] way to do it. Lambda, map, and reduce were all components that Guido very much wanted to remove, as he felt they had no place in Python.
Python is an object-oriented language, and the fact that it is a more purely object oriented language than (for example) Java allows one to use functions as first-class objects in ways that appear to be consistent with a functional paradigm, but that doesn't mean that the language supports a functional approach. That would require support by the interpreter for some key
Put another way, what's the difference between the following?
> [f(x) for x in xrange(10)]
> map(f, range(10))
Without knowing the difference in the underlying implementation, you can't really be sure - it's possible that map() is just a syntactic alternative to a list comprehension, and you could write an implementation of Python that did just that. If we're talking about CPython, though (which we are), then we have to know that the latter is using a function object that is retrieved once and called multiple times, and the former is using a function object that is retrieved ten times. In the latter case, we have a function object that contains a bound method which receives the implicit parameter 'self' and an integer within the range specified, and this method call is what is, in idiomatic Python, producing the values that are then used to create the list. Also, xrange is using a generator, which requires several function calls in itself, whereas range creates a list (which is handled differently).
That isn't necessarily so inconsistent with a functional paradigm, but my point is that the implementation is more important than the function names - simply saying that map() and reduce() exist doesn't mean that Python is a multiparadigm language. Python is incredibly eager-evaluating and it does not optimize tail recursion, two things which make it hard to argue that Python supports a truly functional style.
As noted by another commenter, this is not an accident; while you can fake functional paradigms syntactically with Python's extensive implementation of first-class objects (including functions), the explicit goal is to discourage use of recursion, as well as other functional ways of thinking, in favor of iteration, and other imperative/OO ways of thinking.
It's not a matter of in-place mapping, but if I remember correctly, map() returns a generator in Python3, which has the effect of simulating single-traversal and lazy evaluation like Haskell does.
> mutability is a property of data-structures, not of functions
True, but in a (purely) functional language, if all data structures are immutable and functions are simply mappings of input values to output values with no side-effects, that's inconsequential. We're talking about simulating a functional paradigm within a non-functional language with mutable data structures, so writing functions without side-effects would be more idiomatic - hence the problems with trying to write Python in a functional style.