How to save a "self" variable in python? [duplicate] - python

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 7 years ago.
In python, inside a class, it appears that when I save a "self" variable into another one, if I edit the new variable, the "self" is also edited:
undropped_lines = self.flagged_lines
print self.flagged_lines
del undropped_lines[0]
print self.flagged_lines
How should one avoid this trait in the code?

This is because lists are mutable and when you say undropped_lines = self.flagged_lines you are just pointing a new name at the same instance.
If you want a copy use undropped_lines = self.flagged_lines[:]

This is because undropped_lines and self.flagged_lines are pointing to the same data. Think of it as two different "names" pointing to the same entity.
You can get around this by creating a shallow copy of the list when assigning to undropped_lines. Something like:
undropped_lines = list( self.flagged_lines )

Related

Assignment to global vs local variables of different types in Python [duplicate]

This question already has answers here:
Why isn't the 'global' keyword needed to access a global variable?
(11 answers)
Closed 6 months ago.
cache = {}
def func():
cache['foo'] = 'bar'
print cache['foo']
output
bar
Why does this work and why doesn't it require use of the global keyword?
Because you are not assigning to cache, you are changing the dictionary itself instead. cache is still pointing to the dictionary, thus is itself unchanged. The line cache['foo'] = 'bar' translates to cache.__setitem__('foo', 'bar'). In other words, the value of cache is a python dict, and that value is itself mutable.
If you tried to change what cache refers to by using cache = 'bar' instead, you would be changing what cache points to and then you need the global keyword.
Perhaps this older answer of mine to a similar question helps you understand the difference: Python list doesn't reflect variable change.

Why is a return statement required in this Python function and not the other? [duplicate]

This question already has answers here:
Why isn't the 'global' keyword needed to access a global variable?
(11 answers)
Closed 6 months ago.
cache = {}
def func():
cache['foo'] = 'bar'
print cache['foo']
output
bar
Why does this work and why doesn't it require use of the global keyword?
Because you are not assigning to cache, you are changing the dictionary itself instead. cache is still pointing to the dictionary, thus is itself unchanged. The line cache['foo'] = 'bar' translates to cache.__setitem__('foo', 'bar'). In other words, the value of cache is a python dict, and that value is itself mutable.
If you tried to change what cache refers to by using cache = 'bar' instead, you would be changing what cache points to and then you need the global keyword.
Perhaps this older answer of mine to a similar question helps you understand the difference: Python list doesn't reflect variable change.

Python make list copy, not reference [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 8 years ago.
I have list of int's called board in python code. I wan't to know, if it was modified, so I have code
self.oldboard = list(self.board)
#here is board modified, if it is possible
if not self.oldboard == self.board:
#this should execute only when board was modified
But oldboard is always equals to board, when I modify board, it modifies oldboard. How to make oldboard just copy of board, not reference?
When copying lists by the slice method (analogous to what you're currently doing):
new_list_copy = old_list[:]
you'll only get a "shallow" copy of the contents. This isn't suitable for lists that contain lists ("nested lists").
If you're trying to copy a nested list, a Pythonic solution is to use deepcopy from the copy module:
import copy
new_list_copy = copy.deepcopy(old_list)
Integers are immutable. I would recommend you familiarize yourself with the notions of shallow and deep copy operations, which you can find in the Python Docs here . In your case you most likely need to use deepcopy, as I would guess that you have several nested lists.

Why does this program change the list with no return value? [duplicate]

This question already has answers here:
How do I pass a variable by reference?
(39 answers)
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Closed 8 years ago.
def main():
a = [1, 2, 3]
myFunc(a)
print(a)
def myFunc(myList):
myList[1] = 100
Im studying for my final for my first compsci class about python. This code came up and I dont understand why the value of the list changes when the myFunc() doesnt have a return value. Why doesn't it just print out 1,2,3? Thank you for your time.
Python lists are mutable. Python functions pass arguments by assignment. When you call main it creates a list and associates it with the local (to main) name a. It then calls myFunc, which assigns this same list as the value of the local (to myFunc) name myList, which mutates it. (I.e., no copy of the list is made; myFunc is working with the same mutable object.) Control then flows back to main, which prints the (now changed) value of a.
I'm currently taking an intro class to Python too so I'll just try my best to answer this question.
Simply put, not all functions need to return a value.
In your function, MyFunc, you effectively changed the list without having to return a value. You just took an extra step to make your program more organized. It would be the same if you just had the contents of your function inside the main function.

Why is the global keyword not required in this case? [duplicate]

This question already has answers here:
Why isn't the 'global' keyword needed to access a global variable?
(11 answers)
Closed 6 months ago.
cache = {}
def func():
cache['foo'] = 'bar'
print cache['foo']
output
bar
Why does this work and why doesn't it require use of the global keyword?
Because you are not assigning to cache, you are changing the dictionary itself instead. cache is still pointing to the dictionary, thus is itself unchanged. The line cache['foo'] = 'bar' translates to cache.__setitem__('foo', 'bar'). In other words, the value of cache is a python dict, and that value is itself mutable.
If you tried to change what cache refers to by using cache = 'bar' instead, you would be changing what cache points to and then you need the global keyword.
Perhaps this older answer of mine to a similar question helps you understand the difference: Python list doesn't reflect variable change.

Categories

Resources