I have a question about the map function in Python.
From what I understand, the function does not mutate the list it’s operating on, but rather create a new one and return it. Is this correct ?
Additionally, I have the following piece of code
def reflect(p,dir):
if(dir == 'X'):
func = lambda (a,b) : (a * -1, b)
else:
func = lambda (a,b) : (a, b * -1)
p = map(func,p)
print 'got', p
points is an array of tuples such as: [(1, 1), (-1, 1), (-1, -1), (1, -1)]
If I call the above function in such a manner:
print points
reflect(points,'X')
print points
the list points does not change. Inside the function though, the print function properly prints what I want.
Could someone maybe point me in some direction where I could learn how all this passing by value / reference etc works in python, and how I could fix the above ? Or maybe I’m trying too hard to emulate Haskell in python…
Thanks
edit:
Say instead of p = map(func,p) I do
for i in range(len(p)):
p[i] = func(p[i])
The value of the list is updated outside of the function, as if working by reference. Ugh, hope this is clear :S
You misunderstand how references work in Python. Here, all names are references, there are no “values”. Names are bound to objects. But
=doesn’t modify the object that’s pointed to by the name — it rebinds the name to a different object:To modify the object itself, it needs to be mutable — i.e. expose members that mutate it or have a modifiable dict. The same thing as above happens when you rebind
p— it doesn’t touchpointsat all, it simply modifies the meaning of localpname.If you want to simulate C++-like references, you need to encapsulate the object into a mutable container, e.g. a list.
But you shouldn’t, at least in this case — you should just return the new object instead.
Well, now that I think about it, you can also do
But again, returning new object is usually better.