Python display function passing by reference / value?

I have a question about the map function in Python.

From what I understand, the function does not mutate the list in which it works, but creates a new one and returns it. Is it correct?

In addition, I have the following code snippet

 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, for example: [(1, 1), (-1, 1), (-1, -1), (1, -1)]

If I call the function above in this way:

 print points reflect(points,'X') print points 

the points list does not change. Inside the function, however, the print function correctly prints what I want.

Maybe someone can point me in some direction where I could find out how all this is passed by value / reference, etc. works on python and how can I fix this? Or maybe I'm trying too hard to imitate 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 list value is updated outside the function, as if working by reference. Fu, hope this is clear: S

+6
source share
3 answers

You misunderstand how Python links work. Here, all names are links, there are no "values". Names are tied to objects. But = does not change the object that the name points to - it rewrites the name to another object:

 x = 42 y = x # now: # 'is' is a identity operator โ€” it checks whether two names point to the # exact same object print x is y # => True print x, y # 42 42 y = 69 # now y has been rebound, but that does not change the '42' object, nor rebinds x print x is y # => False print x, y # 42 69 

To change the object itself, it must be changed - i.e. expose elements that mutate it or have a modifiable dict. The same thing as above happens when you rebuild p - it doesn't touch points at all, it just changes the value of the local name p .

If you want to simulate C ++ links, you need to encapsulate the object in a mutable container, for example. list.

 reflect([points], 'X') # inside reflect: p[0] = ... 

But you should not, at least in this case - you should simply return a new object.

 points = reflect(points, 'X') # inside reflect, instead of p = ... return map(func, p) 

Well, now that I think about it, you can also do

 p[:] = map(func, p) 

But again, returning a new object is usually better.

+12
source

The Python data model is based on a trilogy:
identifier - link - object

.

  • An identifier is a string written in code.
  • A reference is a stricto sensu variable, that is, "a piece of memory whose contents may vary." The link value is the address of the object.
  • the object has an implementation based on the structures of the C language, which is the foundation of Python.

Other words are also used to mean "identifier":
1) name
2) a variable; because this word is used in metonymy in mathematics to refer to symbols representing real mathematical variables, and the variables on the computer are conceptually the same as mathematical variables (their values โ€‹โ€‹can change). In my opinion, this use in Python is a very bad habit: it creates ambiguity and confusion with what is called a "variable" in computer science: "a piece of memory, the contents of which can change."

Best used word: id

.

The identifier and object are bound in a specific namespace. Namespaces are displayed as Python dictionaries, but they are NOT dictionaries.

  • Linking ID and Object indirectly through a link.

  • Linking the identifier and the link is direct and implemented in the SYMBOL TABLE table (or character table).

In computer science, a symbol table is a data structure used by a language translator, such as a compiler or interpreter, where each identifier in the program source code is associated with information regarding its statement or appearance in the source, for example, its type, scope and sometimes its location.
http://en.wikipedia.org/wiki/Symbol_table

They say: identifiers. Right
I rarely see hints of a character table, although this is a key thing that sheds light on the work of the IMO data model in Python.

In my opinion, the word

binding

does not mean an exact and unique mechanism, but at the global level, the set of all mechanisms related to the identifier of the trilogy is reference-object

.

I donโ€™t pretend that I understand perfectly all the issues regarding data models and Python execution, and that the above considerations are more accurate and accurately expressed what can be done.
However, they allow me to have an operational understanding of what happens during code execution.
I would be very happy if I were corrected in some cases, if I am mistaken (for example, I am very pleased that I learned from Michael Fored that the nature of namespaces is not a dictionary, which is just how they are presented)

.

However, I donโ€™t know what is called meaning and reference when discussing the subject of passing something as an argument in Python, and I get the impression that many people who have spoken out on this subject in numerous esoteric discussions no longer know me . I think there is no better and clear opinion on this issue that this Alex Martelli:

"An attempt to reuse terminology, which more generally applies to languages โ€‹โ€‹where" variables are rectangles "in a language where there are" variable post-it tags ", IMHO, rather confuse than help."

Alex Martelli

http://bytes.com/topic/python/answers/37219-value-reference

0
source

I want to do this. The answers really do not answer the question - they ignore the fact that the OP was able to achieve the desired result, iteration. The question comes down to map behavior. Here is a more direct example:

 f=(lambda pair: pair[0].append(pair[1])) a = ([],1) f(a) print(a) #prints ([1],1) a=([],1) map(f,[a]) print(a) #prints ([0],1) 

Thus, the map does not mutate objects in anticipation of OP. I have the same confusion.

Can someone comment on what is happening here? I think this would be a good answer to the OP question.

Note that we have a different behavior if we assign the map output as follows (as requested by Cat Plus Plus)

 f=(lambda pair: pair[0].append(pair[1])) a = ([],1) x = [a] x[:] = map(f,x) print(x) #prints None print(a) # prints [1] 

Note that in the first example, we simply call f(a) , not a=f(a) . Why do we need assignment when using map , and not when working outside of map ?

0
source

Source: https://habr.com/ru/post/895962/


All Articles