This question already has answers here:
Why does += behave unexpectedly on lists?
(9 answers)
Closed 6 years ago.
I don't understand why these functions give different results; I thought that s+= and s=s+ were equivalent:
def foo(s):
s += ['hi']
def foo2(s):
s = s + ['hi']
But the first modifies the list s and the second does not. Could someone help me clarifying this?
x+= y is same as x = x + y only for immutable types. For mutable types, the option exists to alter the object in-place. So for lists, += is the same as list.extend() followed by a re-bind of the name.
Read: Augmented Assignment Statements and Why does += behave unexpectedly on lists? for more information.
Use list.append because if you say s = s +['hi'] then s just point to another object, but if you use .append() then the same list is being changed
Related
This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 13 days ago.
This snippet of python code
def changeValue(x):
x = 2*x
a = [1]
changeValue(a[0])
print(a[0])
Will print the result "1" when I would like it to print the result "2". Can this be done by only altering the function and no other part of the code? I know there are solutions like
def changeValue(x):
x[0] = 2*x[0]
a = [1]
changeValue(a)
or
def changeValue(x):
return 2*x
a = [1]
a[0] = changeValue(a[0])
I am wondering if the argument passed as-is can be treated as a pointer in some sense.
[edit] - Just found a relevant question here so this is likely a duplicate that can be closed.
No it's not possible. If you pass a[0], it's an int and it can't be mutated in any way.
If the int was directly in the global namespace, you could use global keyword. But it's not. So again no.
This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 1 year ago.
def double_reverse(words_list):
reverse = []
reverse1= []
reverse = words_list[::-1]
for i in reverse:
reverse1.append(i[::-1])
words_list = reverse1
Hi there,
I have this question for a practice assessment:
Question
For this question, I cannot return or print anything. Instead, I need to update the words_list list value so that I can get the desired result.
However, for some reason I can only get the original list. Why is the list not being updated?
Cheers
words_list = reverse1
just rebinds the local variable words_list. It does not mutate the object that this variable referenced before (the one that got passed in as a function argument). A simple fix would be slice assignment:
words_list[:] = reverse1
which constitutes a mutation on said object.
A general pythonic simplification of your function could be:
def double_reverse(words_list):
words_list[:] = [w[::-1] for w in reversed(words_list)]
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 7 years ago.
Is there any difference between these two ways of returning lists?
Initially the list is empty.
my_list = []
method 1:
my_list.append(1)
return my_list
method 2
return my_list.append(1)
Actually, the second method is returning an empty list for me. Please clarify why it is happening like this
When you type the following:
return my_list
You are returning a list object. When you type the following:
return my_list.append(something)
You are returning the result of that method call. In the case of .append() that method is void, so you are effectively returning nothing. If the method .append() appended the argument you pass to it and then returned the modified list itself then you could do it, but that isn't the case.
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 5 months ago.
I need to understand why :
years = range(2010,2016)
years.append(0)
is possible, returning :
[2010,2011,2012,2013,2014,2015,0]
and
years = range(2010,2016).append(0)
or
years = [0].extend(range(2010,2016))
doesn't work ?
I understand that it is a type error from the message I got. But I'd like to have a bit more explanations behind that.
You are storing the result of the list.append() or list.extend() method; both alter the list in place and return None. They do not return the list object again.
Do not store the None result; store the range() result, then extend or append. Alternatively, use concatenation:
years = range(2010, 2016) + [0]
years = [0] + range(2010, 2016)
Note that I'm assuming you are using Python 2 (your first example would not work otherwise). In Python 3 range() doesn't produce a list; you'd have to use the list() function to convert it to one:
years = list(range(2010, 2016)) + [0]
years = [0] + list(range(2010, 2016))
append and extend operations on lists do not return anything (return just None). That is why years is not the list you expected.
In Python 3 range returns an instance of the range class and not a list. If you want to manipulate the result of range you need a list, so:
years = list(range(2010,2016))
years.append(2016)
Finally, (and similarly to the append above) extend operates on the list you're calling it from rather than returning the new list so:
years = list(range(2010,2016))
years.extend( list(range(2016,2020)))
*While Python 2's range function does return a list, the above code will still work fine in Python 2*
Hope this helps!
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 8 years ago.
I wanted to efficiently set a bunch of variables to an empty list. However, using this method, operations on one variable seem to apply to all:
>>> r1,r2,r3,r4,r5,r6,r7,r8=[[]]*8
>>> r1
[]
>>> r1+=[2]
>>> r1,r2
([2], [2])
Why is this? Also, what is the most efficient method that leaves each variable independent?
Doing [[]]*8 creates a list of eight references to the same list object. That is why they all get affected when you update one. To make eight unique lists, use a generator expression:
r1,r2,r3,r4,r5,r6,r7,r8 = ([] for _ in range(8))
You might also use a list comprehension:
r1,r2,r3,r4,r5,r6,r7,r8 = [[] for _ in range(8)]