Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
A real newby question... Is shuffle a time travelling operation?
-
These four lines are in a def setup function
self.emoji_original = self.emoji_names print(self.emoji_original) # result is alphabetic as expected shuffle(self.emoji_names) print(self.emoji_names, self.emoji_original)``` Why does the second print show that both arrays have been shuffled?
-
Lists in python are objects, so when you modify one, both references are affected, since they refer to the same object.
x=[1,2,3] y=x print(id(y)==id(x))
Use .copy() to get a new copy that won't affect the original
z=x.copy() print(id(z)==id(x))
-
Aargh, this may explain some other faux pas I have been making.
Why??! This feels very counter-intuitive changing the meaning of equals in this way.
I guess way back in the mists of time the original Python developer had a reason!
So actually the operator was the time traveller! (Or rather the temporal cloner!)so I was confident it had its own object idI am getting ever more convinced that I do not understand the operation of “self”
Can you point me to some text that would help me... it feels like self is not always self, and often self is “not defined’ when I know it had been!?I would have preferred
B = A transferred contents of A to B just thus once
B == A results in B becoming the same as A for all timeBut then I am just wishing that the Python Language understood me, rather than me having to understand it!
To be clear this only applies to lists right?
A = 1
B = A
A = 2
Won’t change B to 2So, are there any other types of variables where the operators change what they do?
It would be useful to know now! Rather than be struggling with coding issues ;-)
-
@adrius42 said:
Why??! This feels very counter-intuitive changing the meaning of equals in this way.
I guess way back in the mists of time the original Python developer had a reason!
So actually the operator was the time traveller! (Or rather the temporal cloner!)IIRC, most languages do this. It allows some usefull stuff which would otherwise be impossible.
For example, assume you had the following code:def add_defaults(l): """add some default values""" if "value_default" not in l: l.append("value_default") def remove_invalid_values(l): """remove all invalid values from list""" ... some_values = ask_user_for_input() add_default_values(some_values) remove_invalid_values(some_values) print(some_values)
Due to having the same list shared between the functions, we can avoid unneccessary assignments. This is both easier and way more efficient.
But the more important reason is consistency:
list
are objects. This is the same in many programming languages due to the way they work. And all non-primitve objects (maybe there are some exceptions, but none important) are not directly assigned to a variable. Instead, when you saysome_object = SomeObject()
,SomeObject()
is created somewhere in your RAM and a reference is created which points toSomeObject()
. This reference is then assigned tosome_object
. When you usesome_var = some_object
,some_var
actually gets a copy of the reference, likesome_var = some_int
would do, but the copy of the reference still points to the same object. Thus, even ifsome_var
is a copy of the reference insome_object
, it still points to the same object.
Maybe this code can explain this a bit better:class SomeClass(object): """some class""" def __init__(self, v): v = v int_var_a = 1 # int_var_a is directly assigned the integer 1 int_var_b = int_var_a # int_var_a is loaded, and the content is assigned to int_var_b print(int_var_a == int_var_b) # True, both are equal int_var_a = 2 print(int_var_a == int_var_b) # False obj_var_a = SomeClass("value_1") # an instance of SomeClass() is created and stored in the RAM. A reference pointing to SomeClass() is created and assigned to obj_var_a obj_var_b = obj_var_a # the >reference< if obj_car_a is copied to obj_var_b print(obj_var_a.v == obj_var_b.v) # True, because both obj_var_* point to the same object obj_var_b.v = "some other value" # the object is modified, but both obj_var_* still point to the same object print(obj_var_a == obj_var_b) # True, because both obj_var_* still point to the same object and both have been modified
I am getting ever more convinced that I do not understand the operation of “self”
Can you point me to some text that would help me... it feels like self is not always self, and often self is “not defined’ when I know it had been!?self
is in fact not a operation, but a variable name without any real meaning.
Here is some more code:class MyClass(object): def method_a(self, x): # self points to the instance of MyClass() this method is called on. x is some other value pass def method_b(foo, x): # foo points to the instance of MyClass() this method is called on. x is some other value # this is because the first parameter of a bound method is always the object pass @staticmethod def some_static_method(x): #This is a static method. self is not defined here. x is some other value passed to this method. pass @classmethod def some_class_method(cls, x): # This is a class method. cls is not pointing to the instance of the object this is called on, but instead pointing to the class this is called on. # this is useful for alternative constructors
In other words:
self
is always defined if you name the first parameter/argument of a bound (more about that later) methodself
. If you name the first parameter/argument of a bound methodfoo
, thenfoo
would be the equivalent ofself
.
A bound method is a normal method of an instance of a class. In the above example,MyClass().method_a
andMyClass().method_b
are bound methods, because they are "normal" methods (not modified by@staticmethod
or@classmethod
) of an instance (MyClass()
).
If you useMyClass.method_a
orMyClass.method_b
(please note the missing()
, this is the class, not instances of the class), these are unbound methods, as they are not part of an instance. In this case,self
must be specifically passed to the method.Also, about
self
: you can think aboutself
as some sort of namespace.self
is unique per instance of a class. Changes toself
persist between methods of the same instance, but not between methods of different instances.I would have preferred
B = A transferred contents of A to B just thus once
B == A results in B becoming the same as A for all timeIn python,
==
means a comparsion of equality.But then I am just wishing that the Python Language understood me, rather than me having to understand it!
Dont worry, you are not the only one...
To be clear this only applies to lists right?
A = 1
B = A
A = 2
Won’t change B to 2So, are there any other types of variables where the operators change what they do?
This behavior applies to all non-primitive types.
Some example of primitive types areint
,long
andfloat
.
Non-primitive types are basically everything else, mostly instances of classes.
So,a={}; b=a; b["a"] = 2
would also modifya
.
a=1; b=a; b=2
would not changea
, because bothb
anda
are primitive.
Strings are interesting. They are objects, but immutable.a=""; b=a; some_change(b)
would changea
too, but since neithera
norb
can be changed, this is not a problem.Small disclaimer: I am not involved with the development of python and can thus not guarantee that the above information is correct, but it should be.
Sorry for my bad english, it is not my native language. I still hope that this may be of help for you.
-
Out of curiosity, do you come from a Matlab background? Matlab is a little unique in that matricies act like primitives, not objects, and so assigning a matrix to another variable creates a copy (though, a sort of delayed copy that only takes the performance penalty if you modify it).
This for me led to many mistakes when first learning python.
-
Much older! Algol then, Basic. More recently Arduino and Sphero!
I am restarting my coding activities and try to keep my brain active!
And to get ahead of my grandchildren for a millisecond or two! -
@bennr01 Thank you muchly for taking the time to answer my musings.
I assure you, that your English is not the problem, in my comprehension of these concepts, it is much more my lack of understanding!
I will spend the time to extract the wisdom from your response. Thankyou!
-
@adrius42 Very old, indeed. I knew also Algol, like Fortran, Pl/1, Cobol, Apl and all IBM Main frames languages, all were not object oriented, thus all variables were "native", thus this difference did not exist.
Welcome in the world of Pythonista, marvelous app for retired people 😂