What is the difference between `a` and `a[:]` [duplicate] - python

This question already has answers here:
List assignment with [:]
(6 answers)
Closed 8 years ago.
Reading the Python 3.2 tutorial here, towards the end one of the examples is
a[:] = []
Is this equivalent to
a = []
? If it is, why did they write a[:] instead of a? If it isn't, what is the difference?

They are not equivalent. These two examples should get you to understand the difference.
Example 1:
>>> b = [1,2,3]
>>> a = b
>>> a[:] = []
>>> print b
[]
Example 2:
>>> b = [1,2,3]
>>> a = b
>>> a = []
>>> print b
[1,2,3]

That is explained, as you would expect, right there were they use it:
This means that the following slice returns a shallow copy of the list a

The second line doesn't modify the list, it simply arranges for a to point to a new, empty, list. The first line modifies the list pointed at by a. Consider this sample seesion in the python interpreter:
>>> b=[1,2,3]
>>> a=b
>>> a[:]=[]
>>> a
[]
>>> b
[]
Both a and b point to the same list, so we can see that a[:]=[] empties the list and now both a and b point to the same empty list.

Related

Copy a list of list by value and 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)
Copying nested lists in Python
(3 answers)
Closed 4 years ago.
To understand why I was getting an error in a program , in which I tried to find the "minor" of a determinant, I wrote a simpler program because my variables were messed up. This function below takes in a 2 * 2 matrix as an input, and returns a list containing its rows (pointless and inefficient, I know, but I'm trying to understand the theory behind this).
def alpha(A): #where A will be a 2 * 2 matrix
B = A #the only purpose of B is to store the initial value of A, to retrieve it later
mylist = []
for i in range(2):
for j in range(2):
del A[i][j]
array.append(A)
A = B
return mylist
However, here it seems that B is assigned the value of A dynamically, in the sense that I'm not able to store the initial value of A in B to use it later. Why is that?
Because python passes lists by reference
This means that when you write "b=a" you're saying that a and b are the same object, and that when you change b you change also a, and viceversa
A way to copy a list by value:
new_list = old_list[:]
If the list contains objects and you want to copy them as well, use generic copy.deepcopy():
import copy
new_list = copy.deepcopy(old_list)
Since Python passes list by reference, A and B are the same objects. When you modify B you are also modifying A. This behavior can be demonstrated in a simple example:
>>> A = [1, 2, 3]
>>> def change(l):
... b = l
... b.append(4)
...
>>> A
[1, 2, 3]
>>> change(A)
>>> A
[1, 2, 3, 4]
>>>
If you need a copy of A use slice notation:
B = A[:]
A looks like a reference type, not a value type. Reference types are not copied on assignment (unlike e.g. R). You can use copy.copy to make a deep copy of an element

Resolution of an append to an empty array [duplicate]

This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 6 years ago.
I noticed something odd demonstrated below:
>>> print [].append(1)
None
>>> a = [].append(1)
>>> print a
None
>>> a = []
>>> a.append(1)
>>> print a
[1]
I do not understand what the difference between the first two statements and the last one is. Can anyone explain?
EDIT:
This question was asked poorly. I should also have noted that:
>>> print [] + [1]
[1]
Thank you for explaining that the return value for operations on mutable data-types in python is normally None.
The .append() method does not return a modified list as you would expect.
With this line a = [].append(1) you're assigning the return value (which is None in Python by default) to the variable a. You're not assigning an array that you've just appended to.
However, with this code
>>> a = []
>>> a.append(1)
you're modifying the array in the variable a.

list.append() in python returning null [duplicate]

This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 6 years ago.
What is the actual difference between list1.append() and list1+list2 in python??
Along with this, why the following statement return NULL?
print(list1.append(list2))
{where list1 and list2 are 2 simple list}
list.append() modifies the object and returns None.
[] + [] creates and "returns" new list.
https://docs.python.org/2.7/tutorial/datastructures.html#more-on-lists
Recommended reading: http://docs.python-guide.org/en/latest/writing/gotchas/
Returning None is a way to communicate that an operation is side-effecting -- that is, that it's changing one of its operands, as opposed to leaving them unchanged and returning a new value.
list1.append(list2)
...changes list1, making it a member of this category.
Compare the following two chunks of code:
# in this case, it's obvious that list1 was changed
list1.append(list2)
print list1
...and:
# in this case, you as a reader don't know if list1 was changed,
# unless you already know the semantics of list.append.
print list1.append(list2)
Forbidding the latter (by making it useless) thus enhances the readability of the language.
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a.append(b) # append just appends the variable to the next index and returns None
>>> print a
[1,2,3,[4,5,6]]
>>> a.extend(b) # Extend takes a list as input and extends the main list
[1,2,3,4,5,6]
>>> a+b # + is exactly same as extend
[1,2,3,4,5,6]
When you print a function, you print what it returns and the append method does not return anything. However your list now has a new element. You can print the list to see the changes made.
list1 + list2 means that you combine 2 lists into one big list.
list1.append(element) adds one element to the end of the list.
Here's an example of append vs +
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a + b
[1, 2, 3, 4, 5, 6]
>>>
>>> a.append(b)
>>> a
[1, 2, 3, [4, 5, 6]]

Understanding Python variables assignment [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 9 years ago.
If I execute this code:
a = [1,2,3]
b = a
b.remove(2)
print(a,b)
What I expect to see is:
[1,2,3] [1,3]
But this is what I really get:
[1,3] [1,3]
Why calling b.remove(2) also affects a?
What if I want to change b,while keeping a copy of the original content in a?
When you do b = a, you simply create another reference to the same list. So any modifications to that list will affect both a and b. So doing b.remove(2) will affect the single list that you have.
If you want to get your expected results, you can create a copy of the list:
b = a[:]
This way, you create a copy of the list, and you can modify one without changing the other.
>>> a = [1,2,3]
>>> b = a[:]
>>> b.remove(2)
>>> print a,b
[1, 2, 3] [1, 3]
a and b are two names for the same list, so if you change the list through one name, you can see the changes through the other name. If you want them to be different lists, make a copy:
b = a[:]
or
b = list(a)

Store reference to primitive type in Python?

Code:
>>> a = 1
>>> b = 2
>>> l = [a, b]
>>> l[1] = 4
>>> l
[1, 4]
>>> l[1]
4
>>> b
2
What I want to instead see happen is that when I set l[1] equal to 4, that the variable b is changed to 4.
I'm guessing that when dealing with primitives, they are copied by value, not by reference. Often I see people having problems with objects and needing to understand deep copies and such. I basically want the opposite. I want to be able to store a reference to the primitive in the list, then be able to assign new values to that variable either by using its actual variable name b or its reference in the list l[1].
Is this possible?
There are no 'primitives' in Python. Everything is an object, even numbers. Numbers in Python are immutable objects. So, to have a reference to a number such that 'changes' to the 'number' are 'seen' through multiple references, the reference must be through e.g. a single element list or an object with one property.
(This works because lists and objects are mutable and a change to what number they hold is seen through all references to it)
e.g.
>>> a = [1]
>>> b = a
>>> a
[1]
>>> b
[1]
>>> a[0] = 2
>>> a
[2]
>>> b
[2]
You can't really do that in Python, but you can come close by making the variables a and b refer to mutable container objects instead of immutable numbers:
>>> a = [1]
>>> b = [2]
>>> lst = [a, b]
>>> lst
[[1], [2]]
>>> lst[1][0] = 4 # changes contents of second mutable container in lst
>>> lst
[[1], [4]]
>>> a
[1]
>>> b
[4]
I don't think this is possible:
>>> lst = [1, 2]
>>> a = lst[1] # value is copied, not the reference
>>> a
2
>>> lst[1] = 3
>>> lst
[1, 3] # list is changed
>>> a # value is not changed
2
a refers to the original value of lst[1], but does not directly refer to it.
Think of l[0] as a name referring to an object a, and a as a name that referring to an integer.
Integers are immutable, you can make names refer to different integers, but integers themselves can't be changed.
There were a relevant discussion earlier:
Storing elements of one list, in another list - by reference - in Python?
According to #mgilson, when doing l[1] = 4, it simply replaces the reference, rather than trying to mutate the object. Nevertheless, objects of type int are immutable anyway.

Categories