How do change the list value? [duplicate] - python

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)]

Related

Can you directly alter the value of a non-list argument passed to a function? [duplicate]

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.

Use variable name, not its value [duplicate]

This question already has answers here:
How can you print a variable name in python? [duplicate]
(8 answers)
Closed 2 years ago.
What?
I want to use a variable's name, not it's value. For instance, in the following example, I would like the function to return my_list[1] , and not B..
my_list = ['A', 'B']
def example(list_element):
print(repr(eval(list_element)))
example(my_list[1]) # I would like this to print `my_list[1]`
But Why?
I am trying to create a function that takes a given element from a list, and also uses the previous list element. By getting the name my_list[1], I can subtract one and also get my_list[0]. Once I have both the names, I can utilise the values stored under these names.
Yes, I could simply add two fields to the function and put them in each time but I was hoping to keep the body of my code a little easier to read.
Don't use data to manipulate your code, it's not how Python (or most languages) works.
To do what you're trying to do:
my_list = ['A', 'B']
def example(a_list, index):
print('The element passed: ', a_list[index])
print('The element before it: ', a_list[index-1])
example(my_list, 1)
Of course this doesn't check if you didn't accidentally pass 0, etc. - but it shows you don't need to make a mess with eval, exec, etc.

Passing Lists to function in Python [duplicate]

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

Not able to return list [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 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.

How to get a copy from a list? [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.
I am trying to get an element from list and make some change on this element (which is also a list). Weirdly, the change applied on the previous list. Here is my code:
>>>sentences[0]
['<s>/<s>',
'I/PRP',
'need/VBP',
'to/TO',
'have/VB',
'dinner/NN',
'served/VBN',
'</s>/</s>']
>>>sentence = sentences[0]
>>>sentence.insert(0,startc); sentence.append(endc)
>>>sentences[0]
['<s>/<s>',
'<s>/<s>',
'I/PRP',
'need/VBP',
'to/TO',
'have/VB',
'dinner/NN',
'served/VBN',
'</s>/</s>'
'</s>/</s>']
It is like I just got a pointer to that element, not a copy
You do get a "pointer", in fact. Lists (and any mutable value type!) are passed around as reference in Python.
You can make a copy of a list by passing it to the list() object constructor, or by making a full slice using [:].
a = [1,2,3]
b = a
c = list(a)
d = a[:]
a[1] = 4 # changes the list referenced by both 'a' and 'b', but not 'c' or 'd'
You're exactly right! In Python, when you pass a list as an argument to a function, or you assign a list to another variable, you're actually passing a pointer to it.
This is for efficiency reasons; if you made a separate copy of a 1000-item list every time you did one of the aforementioned things, the program would consume way too much memory and time.
To overcome this in Python, you can duplicate a one-dimensional list using = originalList[:] or = list(originalList):
sentence = sentences[0][:] # or sentence = list(sentences[0])
sentence.insert(0,startc)
sentence.append(endc)
print(sentence) # modified
print(sentences[0]) # not modified
Consider using list comprehension if you need to duplicate a 2D list.

Categories